I have code which reads vast numbers of dates in ‘YYYY-MM-DD’ format. Parsing all these dates, so that it can add one, two, or three days then write back in the same format is slowing things down quite considerably.
JavaScript
x
5
1
3214657 14.330 0.000 103.698 0.000 trade.py:56(effective)
2
3218418 34.757 0.000 66.155 0.000 _strptime.py:295(_strptime)
3
4
day = datetime.datetime.strptime(endofdaydate, "%Y-%m-%d").date()
5
Any suggestions how to speed it up a bit (or a lot)?
Advertisement
Answer
Python 3.7+: fromisoformat()
Since Python 3.7, the datetime
class has a method fromisoformat
. It should be noted that this can also be applied to this question:
Performance vs. strptime()
Explicit string slicing may give you about a 9x increase in performance compared to normal strptime
, but you can get about a 90x increase with the built-in fromisoformat
method!
JavaScript
1
9
1
%timeit isofmt(datelist)
2
569 µs ± 8.45 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
3
4
%timeit slice2int(datelist)
5
5.51 ms ± 48.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
6
7
%timeit normalstrptime(datelist)
8
52.1 ms ± 1.27 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
9
JavaScript
1
23
23
1
from datetime import datetime, timedelta
2
base, n = datetime(2000, 1, 1, 1, 2, 3, 420001), 10000
3
datelist = [(base + timedelta(days=i)).strftime('%Y-%m-%d') for i in range(n)]
4
5
def isofmt(l):
6
return list(map(datetime.fromisoformat, l))
7
8
def slice2int(l):
9
def slicer(t):
10
return datetime(int(t[:4]), int(t[5:7]), int(t[8:10]))
11
return list(map(slicer, l))
12
13
def normalstrptime(l):
14
return [datetime.strptime(t, '%Y-%m-%d') for t in l]
15
16
print(isofmt(datelist[0:1]))
17
print(slice2int(datelist[0:1]))
18
print(normalstrptime(datelist[0:1]))
19
20
# [datetime.datetime(2000, 1, 1, 0, 0)]
21
# [datetime.datetime(2000, 1, 1, 0, 0)]
22
# [datetime.datetime(2000, 1, 1, 0, 0)]
23
Python 3.8.3rc1 x64 / Win10