diff --git a/translations/README-ru.md b/translations/README-ru.md index 032fef9..bb7a1ea 100644 --- a/translations/README-ru.md +++ b/translations/README-ru.md @@ -3430,6 +3430,103 @@ def square(x): ``` #### πŸ’‘ ОбъяснСниС: -+ ΠžΠΏΠ΅Ρ€Π°Π½Π΄ `+=` быстрС `+` для "слоТСния" 2 ΠΈ Π±ΠΎΠ»Π΅Π΅ строк, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ пСрвая строка (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, `s1` for `s1 += s2 + s3`) Π½Π΅ уничтоТаСтся Π²ΠΎ врСмя формирования Ρ„ΠΈΠ½Π°Π»ΡŒΠ½ΠΎΠΉ строки. ++ ΠžΠΏΠ΅Ρ€Π°Π½Π΄ `+=` быстрСС `+` для "слоТСния" 2 ΠΈ Π±ΠΎΠ»Π΅Π΅ строк, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ пСрвая строка (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, `s1` for `s1 += s2 + s3`) Π½Π΅ уничтоТаСтся Π²ΠΎ врСмя формирования Ρ„ΠΈΠ½Π°Π»ΡŒΠ½ΠΎΠΉ строки. + +--- + + +### β–Ά Π‘Π΄Π΅Π»Π°Π΅ΠΌ Π³ΠΈΠ³Π°Π½Ρ‚ΡΠΊΡƒΡŽ строку! + +```py +def add_string_with_plus(iters): + s = "" + for i in range(iters): + s += "xyz" + assert len(s) == 3*iters + +def add_bytes_with_plus(iters): + s = b"" + for i in range(iters): + s += b"xyz" + assert len(s) == 3*iters + +def add_string_with_format(iters): + fs = "{}"*iters + s = fs.format(*(["xyz"]*iters)) + assert len(s) == 3*iters + +def add_string_with_join(iters): + l = [] + for i in range(iters): + l.append("xyz") + s = "".join(l) + assert len(s) == 3*iters + +def convert_list_to_string(l, iters): + s = "".join(l) + assert len(s) == 3*iters +``` + +**Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚:** + +```py +# Π€Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Ρ‹ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ Π² ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠ΅ `ipython` с использованиСм `%timeit` для Π»ΡƒΡ‡ΡˆΠ΅ΠΉ читаСмости Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ². +# Π’Ρ‹ Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ timeit Π² ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠΉ ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠ΅ python shell/scriptm=, ΠΏΡ€ΠΈΠΌΠ΅Ρ€ использования Π½ΠΈΠΆΠ΅ +# timeit.timeit('add_string_with_plus(10000)', number=1000, globals=globals()) + +>>> NUM_ITERS = 1000 +>>> %timeit -n1000 add_string_with_plus(NUM_ITERS) +124 Β΅s Β± 4.73 Β΅s per loop (mean Β± std. dev. of 7 runs, 100 loops each) +>>> %timeit -n1000 add_bytes_with_plus(NUM_ITERS) +211 Β΅s Β± 10.5 Β΅s per loop (mean Β± std. dev. of 7 runs, 1000 loops each) +>>> %timeit -n1000 add_string_with_format(NUM_ITERS) +61 Β΅s Β± 2.18 Β΅s per loop (mean Β± std. dev. of 7 runs, 1000 loops each) +>>> %timeit -n1000 add_string_with_join(NUM_ITERS) +117 Β΅s Β± 3.21 Β΅s per loop (mean Β± std. dev. of 7 runs, 1000 loops each) +>>> l = ["xyz"]*NUM_ITERS +>>> %timeit -n1000 convert_list_to_string(l, NUM_ITERS) +10.1 Β΅s Β± 1.06 Β΅s per loop (mean Β± std. dev. of 7 runs, 1000 loops each) +``` + +Π£Π²Π΅Π»ΠΈΡ‡ΠΈΠΌ число ΠΈΡ‚Π΅Ρ€Π°Ρ†ΠΈΠΉ Π² 10 Ρ€Π°Π·. + +```py +>>> NUM_ITERS = 10000 +>>> %timeit -n1000 add_string_with_plus(NUM_ITERS) # Π›ΠΈΠ½Π΅ΠΉΠ½ΠΎΠ΅ ΡƒΠ²Π΅Π»ΠΈΡ‡Π΅Π½ΠΈΠ΅ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ выполнСния +1.26 ms Β± 76.8 Β΅s per loop (mean Β± std. dev. of 7 runs, 1000 loops each) +>>> %timeit -n1000 add_bytes_with_plus(NUM_ITERS) # ΠšΠ²Π°Π΄Ρ€Π°Ρ‚ΠΈΡ‡Π½ΠΎΠ΅ ΡƒΠ²Π΅Π»ΠΈΡ‡Π΅Π½ΠΈΠ΅ +6.82 ms Β± 134 Β΅s per loop (mean Β± std. dev. of 7 runs, 1000 loops each) +>>> %timeit -n1000 add_string_with_format(NUM_ITERS) # Π›ΠΈΠ½Π΅ΠΉΠ½ΠΎΠ΅ ΡƒΠ²Π΅Π»ΠΈΡ‡Π΅Π½ΠΈΠ΅ +645 Β΅s Β± 24.5 Β΅s per loop (mean Β± std. dev. of 7 runs, 1000 loops each) +>>> %timeit -n1000 add_string_with_join(NUM_ITERS) # Π›ΠΈΠ½Π΅ΠΉΠ½ΠΎΠ΅ ΡƒΠ²Π΅Π»ΠΈΡ‡Π΅Π½ΠΈΠ΅ +1.17 ms Β± 7.25 Β΅s per loop (mean Β± std. dev. of 7 runs, 1000 loops each) +>>> l = ["xyz"]*NUM_ITERS +>>> %timeit -n1000 convert_list_to_string(l, NUM_ITERS) # Π›ΠΈΠ½Π΅ΠΉΠ½ΠΎΠ΅ ΡƒΠ²Π΅Π»ΠΈΡ‡Π΅Π½ΠΈΠ΅ +86.3 Β΅s Β± 2 Β΅s per loop (mean Β± std. dev. of 7 runs, 1000 loops each) +``` + +#### πŸ’‘ ОбъяснСниС + +- ΠŸΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅ ΠΎ [timeit](https://docs.python.org/3/library/timeit.html) ΠΈΠ»ΠΈ [%timeit](https://ipython.org/ipython-doc/dev/interactive/magics.html#magic-timeit) Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ ΠΏΠΎ этим ссылкам. Они ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ для измСрСния Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ выполнСния Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚ΠΎΠ² ΠΊΠΎΠ΄Π°. +- НС ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ `+` для Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ Π΄Π»ΠΈΠ½Π½Ρ‹Ρ… строк - Π’ Python `str` нСизмСняСма, поэтому лСвая ΠΈ правая строки Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ скопированы Π² Π½ΠΎΠ²ΡƒΡŽ строку для ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΏΠ°Ρ€Ρ‹ ΠΊΠΎΠ½ΠΊΠ°Ρ‚Π΅Π½Π°Ρ†ΠΈΠΉ. Если Π²Ρ‹ ΠΊΠΎΠ½ΠΊΠ°Ρ‚Π΅Π½ΠΈΡ€ΡƒΠ΅Ρ‚Π΅ Ρ‡Π΅Ρ‚Ρ‹Ρ€Π΅ строки Π΄Π»ΠΈΠ½Ρ‹ 10, Ρ‚ΠΎ вмСсто 40 символов Π²Ρ‹ скопируСтС (10+10) + ((10+10)+10) + (((10+10)+10)+10) = 90 символов. Π‘ ΡƒΠ²Π΅Π»ΠΈΡ‡Π΅Π½ΠΈΠ΅ΠΌ количСства ΠΈ Ρ€Π°Π·ΠΌΠ΅Ρ€Π° строки ситуация ΡƒΡ…ΡƒΠ΄ΡˆΠ°Π΅Ρ‚ΡΡ Π² ΠΊΠ²Π°Π΄Ρ€Π°Ρ‚ΠΈΡ‡Π½ΠΎΠΉ прогрСссии (Ρ‡Ρ‚ΠΎ подтвСрТдаСтся Π²Ρ€Π΅ΠΌΠ΅Π½Π΅ΠΌ выполнСния Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ `add_bytes_with_plus`). +- ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ рСкомСндуСтся ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ синтаксис `.format.` ΠΈΠ»ΠΈ `%` (ΠΏΡ€Π°Π²Π΄Π°, для ΠΎΡ‡Π΅Π½ΡŒ ΠΊΠΎΡ€ΠΎΡ‚ΠΊΠΈΡ… строк ΠΎΠ½ΠΈ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ ΠΌΠ΅Π΄Π»Π΅Π½Π½Π΅Π΅, Ρ‡Π΅ΠΌ `+`). +- Или Π»ΡƒΡ‡ΡˆΠ΅, Ссли Ρƒ вас ΡƒΠΆΠ΅ Π΅ΡΡ‚ΡŒ содСрТимоС Π² Π²ΠΈΠ΄Π΅ ΠΈΡ‚Π΅Ρ€ΠΈΡ€ΡƒΠ΅ΠΌΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, Ρ‚ΠΎΠ³Π΄Π° ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ `''.join(iterable_object)`, Ρ‡Ρ‚ΠΎ Π³ΠΎΡ€Π°Π·Π΄ΠΎ быстрСС. +- Π’ ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ `add_bytes_with_plus` ΠΈΠ·-Π·Π° ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠΉ `+=`, рассмотрСнных Π² ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅, `add_string_with_plus` Π½Π΅ ΠΏΠΎΠΊΠ°Π·Π°Π»ΠΎ ΠΊΠ²Π°Π΄Ρ€Π°Ρ‚ΠΈΡ‡Π½ΠΎΠ³ΠΎ увСличСния Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ выполнСния. Если Π±Ρ‹ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ Π±Ρ‹Π» `s = s + "x" + "y" + "z"` вмСсто `s += "xyz"`, ΡƒΠ²Π΅Π»ΠΈΡ‡Π΅Π½ΠΈΠ΅ Π±Ρ‹Π»ΠΎ Π±Ρ‹ ΠΊΠ²Π°Π΄Ρ€Π°Ρ‚ΠΈΡ‡Π½Ρ‹ΠΌ. + ```py + def add_string_with_plus(iters): + s = "" + for i in range(iters): + s = s + "x" + "y" + "z" + assert len(s) == 3*iters + + >>> %timeit -n100 add_string_with_plus(1000) + 388 Β΅s Β± 22.4 Β΅s per loop (mean Β± std. dev. of 7 runs, 1000 loops each) + >>> %timeit -n100 add_string_with_plus(10000) # Quadratic increase in execution time + 9 ms Β± 298 Β΅s per loop (mean Β± std. dev. of 7 runs, 100 loops each) + ``` + +- Π’Π°ΠΊΠΎΠ΅ число способов форматирования ΠΈ создания гигантской строки нСсколько ΠΏΡ€ΠΎΡ‚ΠΈΠ²ΠΎΡ€Π΅Ρ‡ΠΈΡ‚ [Zen of Python](https://www.python.org/dev/peps/pep-0020/), согласно ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ, + + > Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ ΠΎΠ΄ΠΈΠ½ - ΠΈ ΠΆΠ΅Π»Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ - ΠΎΡ‡Π΅Π²ΠΈΠ΄Π½Ρ‹ΠΉ способ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ это. ---