dememax: (скука)
[personal profile] dememax
Если захотите поиграться с производительностью какого-нибудь кода на питоне прямо из командной строки, вот на примере из предыдущего поста:
$ python -m timeit -s 'a,b,c = "a", "b", "d"' '"%s%s%s" % (a, b, c)'
10000000 loops, best of 3: 0.153 usec per loop
$ python -m timeit -s 'a,b,c = "a", "b", "d"' 'a + b + c'
10000000 loops, best of 3: 0.0818 usec per loop
$ python -m timeit -s 'a,b,c = "a", "b", "d"' 'f"{a}{b}{c}"'
10000000 loops, best of 3: 0.0668 usec per loop
$ python -m timeit -s 'a,b,c = "a", "b", "d"' '"{}{}{}".format(a, b, c)'
1000000 loops, best of 3: 0.286 usec per loop
Модуль timeit входит в стандартную поставку питона.
Параметр -s позволяет задать начальные условия, которые будут использованы на каждой итерации.

P.S.: Показания выше - были для Python 3.6.10 (default, Mar 22 2020, 04:35:52) [GCC 9.2.0]
Linux maxmsi 4.19.97-gentoo #3 SMP Wed Mar 18 18:23:29 CET 2020 x86_64 Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz GenuineIntel GNU/Linux

Теперь для Python 3.7.7 (default, Mar 29 2020, 19:50:40) [GCC 9.2.0], расширенные и с расшифровкой:
$ python3.7 -m timeit --verbose --number 5000000 --setup 'a,b,c = "a", "b", "d"' \
> 'a + b + c'
raw times: 461 msec, 460 msec, 469 msec, 463 msec, 478 msec

5000000 loops, best of 5: 91.9 nsec per loop
$ python3.7 -m timeit --verbose --number 5000000 --setup 'a,b,c = "a", "b", "d"' \
> '"".join((a, b, c))'
raw times: 614 msec, 627 msec, 637 msec, 648 msec, 647 msec

5000000 loops, best of 5: 123 nsec per loop
$ python3.7 -m timeit --verbose --number 5000000 --setup 'a,b,c = "a", "b", "d"; import io' \
> 'with io.StringIO("", "") as n: n.write(a); n.write(b); n.write(b); n.getvalue()'
raw times: 5.76 sec, 5.9 sec, 6 sec, 5.87 sec, 6.06 sec

5000000 loops, best of 5: 1.15 usec per loop
$ python3.7 -m timeit --verbose --number 5000000 --setup 'a,b,c = "a", "b", "d"' \
> '"%s%s%s" % (a, b, c)'
raw times: 841 msec, 855 msec, 857 msec, 856 msec, 857 msec

5000000 loops, best of 5: 168 nsec per loop
$ python3.7 -m timeit --verbose --number 5000000 --setup 'a,b,c = "a", "b", "d"' \
> '"{}{}{}".format(a, b, c)'
raw times: 1.49 sec, 1.5 sec, 1.51 sec, 1.51 sec, 1.5 sec

5000000 loops, best of 5: 298 nsec per loop
$ python3.7 -m timeit --verbose --number 5000000 --setup 'a,b,c = "a", "b", "d"' \
> 'f"{a}{b}{c}"'
raw times: 367 msec, 400 msec, 376 msec, 372 msec, 373 msec

5000000 loops, best of 5: 73.4 nsec per loop

Т.е., самый худший вариант у io.StringIO.
Самый лучший - 73.4 nsec - у f-string.
Но на втором месте - 91.9 nsec - именно у obvious way.

Это всё ни в коем случае не доказать что-то или вступать в спор, объяснять почему...
Мне был и остаётся очень интересным именно психологический момент, человеческий аспект всей этой истории!
Почему? Потому, что программы пишутся для программистов!

Date: 2020-03-29 06:19 pm (UTC)
juan_gandhi: (Default)
From: [personal profile] juan_gandhi
Вот же ж. Так если string interpolation есть, на хрена еще городить всякую хрень, спрашивается? Ну ладно, проценты, это народная традиция двадцатилетней давности.

Date: 2020-03-31 08:44 am (UTC)
From: [personal profile] sassa_nf
More fun facts:

(Python 2.7)
$ python -m timeit -s 'xs = ["a" for i in xrange(1000)]' 'a = ""
for x in xs:
   a += x
'
10000 loops, best of 3: 47.1 usec per loop
$ python -m timeit -s 'xs = ["a" for i in xrange(100)]' 'a = ""
> for x in xs:
>    a += x
> '
100000 loops, best of 3: 3.32 usec per loop
$ python -m timeit -s 'xs = ["a" for i in xrange(3)]' 'a = ""
for x in xs:
   a += x
'
10000000 loops, best of 3: 0.169 usec per loop


Why all that fuss? Well, I want something comparable to join - one of the issues with "".join((a,b,c)) is that first we need to create the tuple, and the a + b + c doesn't have to. So now that the + is using a list, too, let's see what join does:

$ python -m timeit -s 'xs = ["a" for i in xrange(1000)]' '"".join(xs)'
100000 loops, best of 3: 9.67 usec per loop
$ python -m timeit -s 'xs = ["a" for i in xrange(100)]' '"".join(xs)'
1000000 loops, best of 3: 1.02 usec per loop
$ python -m timeit -s 'xs = ["a" for i in xrange(3)]' '"".join(xs)'
10000000 loops, best of 3: 0.0847 usec per loop


But because the next test should have been the same as the for..., I reckon we are measuring interpreter performance, not really string concatenation overheads:
$ python -m timeit -s 'xs = ["a" for i in xrange(1000)]' 'reduce(lambda a, b: a + b, xs)'
10000 loops, best of 3: 157 usec per loop
From: [personal profile] sassa_nf
:) long live 2.7!

I am not fussed, really, and use whatever is preinstalled on my box.

I am not sure about the difference between 1 and 2 (number of elements in the resulting concatenation)

3 - result length - seems to be what I vary.

I started with 1 - long elements for concatenation. The difference was bigger. (Because of having to copy strings). So then I went looking for what shorter strings already show the difference.

(join 5 long strings vs join 3 long strings)
$ python -m timeit -s 'xs = ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"][:]' '"".join(xs)'
10000000 loops, best of 3: 0.108 usec per loop
$ python -m timeit -s 'xs = ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"][:3]' '"".join(xs)'
10000000 loops, best of 3: 0.085 usec per loop


Then just concatenation (5 vs 3 - 5 is already slower than join, using the preferred approach with no intermediate list or loop):
$ python -m timeit -s 'a,b,c,d,e = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"' 'a+b+c+d+e'
10000000 loops, best of 3: 0.128 usec per loop
$ python -m timeit -s 'a,b,c,d,e = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"' 'a+b+c'
10000000 loops, best of 3: 0.0667 usec per loop

Profile

dememax

May 2023

S M T W T F S
 123456
78910111213
14151617181920
21 2223 24252627
28293031   

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Mar. 4th, 2026 06:10 pm
Powered by Dreamwidth Studios