最有效地从文件中写入和读取LocalDateTime

时间:2017-07-13 22:19:20

标签: java java-8 java-time

import bs4, urlparse, json, requests,csv from os.path import basename as bn links = [] data = {} base = 'http://data-interview.enigmalabs.org/' #Approach #1. Each individual pages, collect the links #2. Iterate over each link in a list #3. Before moving on each the list for links if correct move on, if not review step 2 then 1 #4. Push correct data to a JSON file def bs(r): return bs4.BeautifulSoup(requests.get(urlparse.urljoin(base, r).encode()).content, 'html.parser').find('table') for i in range(1,11): print 'Collecting page %d' % i links += [a['href'] for a in bs('companies?page=%d' % i).findAll('a')] # Search a the given range of "a" on each page # Now that I have collected all links into an list,iterate over each link # All the info is within a html table, so search and collect all company info in data for link in links: print 'Processing %s' % link name = bn(link) data[name] = {} for row in bs(link).findAll('tr'): desc, cont = row.findAll('td') data[name][desc.text.encode()] = cont.text.encode() print json.dumps(data) # Final step is to have all data formating json_data = json.dumps(data, indent=4) file = open("solution.json","w") file.write(json_data) file.close() 实例写入文件然后从文件中读取并将其转换回LocalDateTime对象的最快方法是什么?

我曾经节省了几毫秒,然后将其转换为LocalDateTime对象。它看起来非常快,但现在我正在处理Java 8的Date,并且不清楚从文件中保存和检索它的最有效方法是什么。

我认为使用LocalDateTime不是一个好主意,因为它需要更多资源才能将其转换为DateTimeFormater,然后解析String

时区不相关。

1 个答案:

答案 0 :(得分:1)

如果你想保存毫秒并且时区并不重要,你可以使用java.time.Instant类 - 只有LocalDateTime没有办法获得毫秒,因为这个类没有时区/抵消信息。

// get the current date
Instant instant = Instant.now();

// get milliseconds (equivalent to java.util.Date.getTime())
long millis = instant.toEpochMilli();

// get Instant from milliseconds
Instant instant = Instant.ofEpochMilli(millis);

如果您有LocalDateTime,则可以轻松将其转换为Instant

LocalDateTime d = LocalDateTime.now();
Instant instant = d.atOffset(ZoneOffset.UTC).toInstant();

此代码显然假设LocalDateTime中的值对应于UTC日期和时间。要将Instant转换回LocalDateTime

LocalDateTime d = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);
PS:你有没有测量过系统的性能,知道“快”是否真的是一个问题?无论如何,我正在以“标准”方式(基于API提供的最直接的方式)做事,这是你想要的吗?

也许你可以认为创建一个Instant作为“中间”对象可以减少“快速”(但无论如何你都需要测量它)。如果是这种情况,您可以直接从LocalDateTime获取millis(假设它对应于UTC中的日期和时间):

// get the current date
LocalDateTime d = LocalDateTime.now();
// get milliseconds value
long millis = d.toEpochSecond(ZoneOffset.UTC) * 1000 + d.get(ChronoField.MILLI_OF_SECOND);

// get LocalDateTime from millis
LocalDateTime d = LocalDateTime.ofEpochSecond(millis / 1000, (int) (millis % 1000) * 1000000, ZoneOffset.UTC);

重要的是要注意java.time类具有纳秒精度,因此获得毫秒会使您失去这种精度。

如果您不想丢失纳秒精度并且不一定需要使用毫秒值,则可以存储2个不同的数字(纪元日纳米日) ):

// get the current date
LocalDateTime d = LocalDateTime.now();

// get values from LocalDateTime
long epochDay = d.toLocalDate().toEpochDay();
long nanoOfDay = d.toLocalTime().toNanoOfDay();
// save both values to file

// retrieve the LocalDateTime from the values
LocalDateTime d = LocalDateTime.of(LocalDate.ofEpochDay(epochDay), LocalTime.ofNanoOfDay(nanoOfDay));

这不需要转换为UTC,但它需要2个数字而不是1个。您可能认为创建LocalDateLocalTime会使事情变得更慢,但这两个对象<{>}始终LocalDateTime内部创建(在所有情况下)。< / p>

不确定,如果所有这些数学都比使用Instant“更快”。这是一个测试问题,看看哪一个最适合你的情况。

但对我来说,在清晰度和代码易于维护方面最“有效”的是使用Instant(或使用纪元日的最后一种方法<和<强>纳米一天)。除非你处理数百万条记录,否则我不确定这是否真的会成为性能问题。

我做了一个简单的测试(每个案例运行1000万次以上),最后一种方法(使用纪元日纳米日)似乎是最快的。但差异不到1秒。只运行2次十亿次次,我有20秒的差异,所以如果你要处理这么多记录,也许这是值得的。

关于其他资源(内存使用情况,CPU,I / O),我没有检查。但无论如何,性能问题对每个环境都是非常具体的:取决于系统的设计方式,系统的部件/模块/组件如何相互作用以及许多其他因素,在每种情况下都会有不同的瓶颈。

最后,您必须测试每种方法,看看哪种方法在您的系统中表现最佳。或者你可以得出结论,它没有产生显着的差异(对于少于几百万条记录的情况,也许它没有 - 但你只有在对其进行基准测试后才会知道。)