将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
。
时区不相关。
答案 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个。您可能认为创建LocalDate
和LocalTime
会使事情变得更慢,但这两个对象<{>}始终由LocalDateTime
内部创建(在所有情况下)。< / p>
不确定,如果所有这些数学都比使用Instant
“更快”。这是一个测试问题,看看哪一个最适合你的情况。
但对我来说,在清晰度和代码易于维护方面最“有效”的是使用Instant
(或使用纪元日的最后一种方法<和<强>纳米一天)。除非你处理数百万条记录,否则我不确定这是否真的会成为性能问题。
我做了一个简单的测试(每个案例运行1000万次以上),最后一种方法(使用纪元日和纳米日)似乎是最快的。但差异不到1秒。只运行2次十亿次次,我有20秒的差异,所以如果你要处理这么多记录,也许这是值得的。
关于其他资源(内存使用情况,CPU,I / O),我没有检查。但无论如何,性能问题对每个环境都是非常具体的:取决于系统的设计方式,系统的部件/模块/组件如何相互作用以及许多其他因素,在每种情况下都会有不同的瓶颈。
最后,您必须测试每种方法,看看哪种方法在您的系统中表现最佳。或者你可以得出结论,它没有产生显着的差异(对于少于几百万条记录的情况,也许它没有 - 但你只有在对其进行基准测试后才会知道。)