문자열 연결에 +를 사용해서는 안되며 대신 항상 ''.join을 사용하면 안된다는 가정은 신화 일 수 있습니다. 를 사용 +
하면 불변의 문자열 객체의 불필요한 임시 복사본이 생성 되는 것은 사실 이지만 자주 인용되지 않는 다른 사실은 join
루프에서 호출 하면 일반적으로 function call
. 예를 들어 보겠습니다.
연결된 SO 질문에서 하나와 더 큰 조작으로 두 개의 목록을 만듭니다.
>>> myl1 = ['A','B','C','D','E','F']
>>> myl2=[chr(random.randint(65,90)) for i in range(0,10000)]
두 가지 기능을 만들 수 있습니다 UseJoin
및 UsePlus
각각의 사용 join
과 +
기능을.
>>> def UsePlus():
return [myl[i] + myl[i + 1] for i in range(0,len(myl), 2)]
>>> def UseJoin():
[''.join((myl[i],myl[i + 1])) for i in range(0,len(myl), 2)]
첫 번째 목록으로 timeit을 실행할 수 있습니다.
>>> myl=myl1
>>> t1=timeit.Timer("UsePlus()","from __main__ import UsePlus")
>>> t2=timeit.Timer("UseJoin()","from __main__ import UseJoin")
>>> print "%.2f usec/pass" % (1000000 * t1.timeit(number=100000)/100000)
2.48 usec/pass
>>> print "%.2f usec/pass" % (1000000 * t2.timeit(number=100000)/100000)
2.61 usec/pass
>>>
런타임은 거의 동일합니다.
cProfile을 사용할 수 있습니다.
>>> myl=myl2
>>> cProfile.run("UsePlus()")
5 function calls in 0.001 CPU seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.001 0.001 0.001 0.001 <pyshell#1376>:1(UsePlus)
1 0.000 0.000 0.001 0.001 <string>:1(<module>)
1 0.000 0.000 0.000 0.000 {len}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
1 0.000 0.000 0.000 0.000 {range}
>>> cProfile.run("UseJoin()")
5005 function calls in 0.029 CPU seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.015 0.015 0.029 0.029 <pyshell#1388>:1(UseJoin)
1 0.000 0.000 0.029 0.029 <string>:1(<module>)
1 0.000 0.000 0.000 0.000 {len}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
5000 0.014 0.000 0.014 0.000 {method 'join' of 'str' objects}
1 0.000 0.000 0.000 0.000 {range}
그리고 Join을 사용하면 오버 헤드를 증가시킬 수있는 불필요한 함수 호출이 발생하는 것으로 보입니다.
이제 질문으로 돌아갑니다. 모든 경우 에 +
over join
를 사용하지 말아야합니까 ?
나는 생각하지 않는다.
- 문제의 문자열 길이
- 연결 작업이 없습니다.
그리고 개발 초기 최적화 과정에서 벗어나는 것은 악합니다.