Уведомления

Группа в Telegram: @pythonsu

#1 Окт. 28, 2012 10:46:02

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Все таки, конкатенация строк сложением зло или нет?

python 2.7

def f1():
  d=''
  for i in range(1000):
    d+=str(i)
  return d
  
def f2():
  d=[]
  for i in range(1000):
      d.append(str(i))
  return ''.join(d)
  
if __name__ == '__main__':
    import timeit
    print timeit.timeit("f1()", setup="from __main__ import f1")
    print timeit.timeit("f2()", setup="from __main__ import f2")

Результат теста
220.748425007
249.266052008
Как так, ведь во всех учебниках пишут, что join правильней и быстрее, а на деле получается как то все не так, как пишут.



Офлайн

#2 Окт. 28, 2012 10:57:00

sergeek
Зарегистрирован: 2012-06-26
Сообщения: 470
Репутация: +  43  -
Профиль   Отправить e-mail  

Все таки, конкатенация строк сложением зло или нет?

Наверно подразумевалось что .join лучше использовать в таких случаях:

def f1(ls):
    res = ''
    for n in ls:
        res += n
    return res
def f2(ls):
    return ''.join(ls)
%%timeit
f1(['asdbdf', 'ewfwef', '123123'])
1000000 loops, best of 3: 348 ns per loop
%%timeit
f2(['asdbdf', 'ewfwef', '123123'])
1000000 loops, best of 3: 233 ns per loop

Офлайн

#3 Окт. 28, 2012 11:20:38

dimy44
От: Евпатория
Зарегистрирован: 2012-04-21
Сообщения: 463
Репутация: +  42  -
Профиль  

Все таки, конкатенация строк сложением зло или нет?

Насколько помню, в старых версиях питона конкатенация работала медленно, но в новых версиях ее оптимизировали и она стала чуть быстрее join.

Офлайн

#4 Окт. 28, 2012 11:53:33

odnochlen
Зарегистрирован: 2012-06-28
Сообщения: 794
Репутация: +  14  -
Профиль   Отправить e-mail  

Все таки, конкатенация строк сложением зло или нет?

Я как-то об этом же создавал тему, только найти ее не могу. Как, с одной стороны, строки иммутабельные, а с другой - конкатекация за O(n)?

http://docs.python.org/2/library/stdtypes.html#sequence-types-str-unicode-list-tuple-bytearray-buffer-xrange

6. CPython implementation detail: If s and t are both strings, some Python implementations such as CPython can usually perform an in-place optimization for assignments of the form s = s + t or s += t. When applicable, this optimization makes quadratic run-time much less likely. This optimization is both version and implementation dependent. For performance sensitive code, it is preferable to use the str.join() method which assures consistent linear concatenation performance across versions and implementations.

Changed in version 2.4: Formerly, string concatenation never occurred in-place.
Типа для универсальности - или list и join, или StringIO, или bytearray. Для себя я не парюсь

Офлайн

#5 Окт. 29, 2012 05:18:05

PooH
От:
Зарегистрирован: 2006-12-05
Сообщения: 1948
Репутация: +  72  -
Профиль   Отправить e-mail  

Все таки, конкатенация строк сложением зло или нет?

Что-то я перечитываю этот кусок доки и никак понять не могу, откуда при конкатенации строк появляется квадратичная сложность, с которой они борются?



Вот здесь один из первых отарков съел лаборанта. Это был такой умный отарк, что понимал даже теорию относительности. Он разговаривал с лаборантом, а потом бросился на него и загрыз…

Офлайн

#6 Окт. 29, 2012 09:00:46

odnochlen
Зарегистрирован: 2012-06-28
Сообщения: 794
Репутация: +  14  -
Профиль   Отправить e-mail  

Все таки, конкатенация строк сложением зло или нет?

Отсюда.

s = ""
for t in range(2**16):
    s += 'a'

При сложении создается новый экземпляр строки и копируется содержимое старой. Где-то так:

a
aa
aaa


Видим арифметическую прогрессию, а сумма арифметической прогрессии n*(n+1)/2 => O(n**2) символов надо копировать для создании строки длиной n.

Офлайн

#7 Окт. 29, 2012 11:37:55

PooH
От:
Зарегистрирован: 2006-12-05
Сообщения: 1948
Репутация: +  72  -
Профиль   Отправить e-mail  

Все таки, конкатенация строк сложением зло или нет?

odnochlen
Видим арифметическую прогрессию, а сумма арифметической прогрессии n*(n+1)/2 => O(n**2) символов надо копировать для создании строки длиной n.
Это шутка такая? Вы же внешний цикл в пример ввели, вот квадрат и появился



Вот здесь один из первых отарков съел лаборанта. Это был такой умный отарк, что понимал даже теорию относительности. Он разговаривал с лаборантом, а потом бросился на него и загрыз…

Офлайн

#8 Окт. 29, 2012 11:44:04

odnochlen
Зарегистрирован: 2012-06-28
Сообщения: 794
Репутация: +  14  -
Профиль   Отправить e-mail  

Все таки, конкатенация строк сложением зло или нет?

Проблемы возникают только в цикле, когда таки O(n**2). Цикл, не указан, да. Он, кстати, есть и в твоем примере. Для трех переменных можно писать + и не париться.

Отредактировано odnochlen (Окт. 29, 2012 11:44:46)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version