파이썬의 문자열 연결과 str.join이 얼마나 느립니까?
이 스레드에 대한 내 답변에 대한 의견의 결과로 +=
운영자와 속도 차이가 무엇인지 알고 싶었습니다.''.join()
그렇다면 둘 사이의 속도 비교는 무엇입니까?
From : 효율적인 문자열 연결
방법 1 :
def method1():
out_str = ''
for num in xrange(loop_count):
out_str += 'num'
return out_str
방법 4 :
def method4():
str_list = []
for num in xrange(loop_count):
str_list.append('num')
return ''.join(str_list)
이제 나는 그것들이 엄격하게 대표적이지 않다는 것을 알고 있으며, 네 번째 방법은 각 항목을 반복하고 결합하기 전에 목록에 추가하지만 이는 공정한 표시입니다.
문자열 결합은 연결보다 훨씬 빠릅니다.
왜? 문자열은 변경할 수 없으며 제자리에서 변경할 수 없습니다. 하나를 변경하려면 새로운 표현을 생성해야합니다 (두 표현의 연결).
내 원래 코드가 잘못되었습니다. +
일반적으로 연결이 더 빠른 것 같습니다 (특히 최신 하드웨어의 최신 버전의 Python에서).
시간은 다음과 같습니다.
Iterations: 1,000,000
Windows 7, Core i7의 Python 3.3
String of len: 1 took: 0.5710 0.2880 seconds
String of len: 4 took: 0.9480 0.5830 seconds
String of len: 6 took: 1.2770 0.8130 seconds
String of len: 12 took: 2.0610 1.5930 seconds
String of len: 80 took: 10.5140 37.8590 seconds
String of len: 222 took: 27.3400 134.7440 seconds
String of len: 443 took: 52.9640 170.6440 seconds
Windows 7, Core i7의 Python 2.7
String of len: 1 took: 0.7190 0.4960 seconds
String of len: 4 took: 1.0660 0.6920 seconds
String of len: 6 took: 1.3300 0.8560 seconds
String of len: 12 took: 1.9980 1.5330 seconds
String of len: 80 took: 9.0520 25.7190 seconds
String of len: 222 took: 23.1620 71.3620 seconds
String of len: 443 took: 44.3620 117.1510 seconds
Linux Mint, Python 2.7, 일부 느린 프로세서
String of len: 1 took: 1.8840 1.2990 seconds
String of len: 4 took: 2.8394 1.9663 seconds
String of len: 6 took: 3.5177 2.4162 seconds
String of len: 12 took: 5.5456 4.1695 seconds
String of len: 80 took: 27.8813 19.2180 seconds
String of len: 222 took: 69.5679 55.7790 seconds
String of len: 443 took: 135.6101 153.8212 seconds
다음은 코드입니다.
from __future__ import print_function
import time
def strcat(string):
newstr = ''
for char in string:
newstr += char
return newstr
def listcat(string):
chars = []
for char in string:
chars.append(char)
return ''.join(chars)
def test(fn, times, *args):
start = time.time()
for x in range(times):
fn(*args)
return "{:>10.4f}".format(time.time() - start)
def testall():
strings = ['a', 'long', 'longer', 'a bit longer',
'''adjkrsn widn fskejwoskemwkoskdfisdfasdfjiz oijewf sdkjjka dsf sdk siasjk dfwijs''',
'''this is a really long string that's so long
it had to be triple quoted and contains lots of
superflous characters for kicks and gigles
@!#(*_#)(*$(*!#@&)(*E\xc4\x32\xff\x92\x23\xDF\xDFk^%#$!)%#^(*#''',
'''I needed another long string but this one won't have any new lines or crazy characters in it, I'm just going to type normal characters that I would usually write blah blah blah blah this is some more text hey cool what's crazy is that it looks that the str += is really close to the O(n^2) worst case performance, but it looks more like the other method increases in a perhaps linear scale? I don't know but I think this is enough text I hope.''']
for string in strings:
print("String of len:", len(string), "took:", test(listcat, 1000000, string), test(strcat, 1000000, string), "seconds")
testall()
기존 답변은 매우 잘 작성되고 연구되었지만 Python 3.6 시대에 대한 또 다른 답변이 있습니다. 이제 리터럴 문자열 보간 (AKA, f
-strings)이 있기 때문입니다.
>>> import timeit
>>> timeit.timeit('f\'{"a"}{"b"}{"c"}\'', number=1000000)
0.14618930302094668
>>> timeit.timeit('"".join(["a", "b", "c"])', number=1000000)
0.23334730707574636
>>> timeit.timeit('a = "a"; a += "b"; a += "c"', number=1000000)
0.14985873899422586
2.3GHz에서 Intel Core i7이 장착 된 2012 Retina MacBook Pro에서 CPython 3.6.5를 사용하여 테스트를 수행했습니다.
이것은 결코 공식적인 벤치 마크는 아니지만 f
-strings를 사용하는 것이 +=
연결 을 사용 하는 것만 큼 성능이 뛰어난 것처럼 보입니다 . 물론 개선 된 지표 나 제안을 환영합니다.
이것은 어리석은 프로그램이 테스트하도록 설계된 것입니다. :)
플러스 사용
import time
if __name__ == '__main__':
start = time.clock()
for x in range (1, 10000000):
dog = "a" + "b"
end = time.clock()
print "Time to run Plusser = ", end - start, "seconds"
출력 :
Time to run Plusser = 1.16350010965 seconds
이제 조인으로 ....
import time
if __name__ == '__main__':
start = time.clock()
for x in range (1, 10000000):
dog = "a".join("b")
end = time.clock()
print "Time to run Joiner = ", end - start, "seconds"
출력 :
Time to run Joiner = 21.3877386651 seconds
따라서 Windows의 Python 2.6에서는 +가 join보다 약 18 배 빠릅니다. :)
마지막 답변을 다시 썼습니다. 제가 테스트 한 방식에 대한 의견을 공유해 주시겠습니까?
import time
start1 = time.clock()
for x in range (10000000):
dog1 = ' and '.join(['spam', 'eggs', 'spam', 'spam', 'eggs', 'spam','spam', 'eggs', 'spam', 'spam', 'eggs', 'spam'])
end1 = time.clock()
print("Time to run Joiner = ", end1 - start1, "seconds")
start2 = time.clock()
for x in range (10000000):
dog2 = 'spam'+' and '+'eggs'+' and '+'spam'+' and '+'spam'+' and '+'eggs'+' and '+'spam'+' and '+'spam'+' and '+'eggs'+' and '+'spam'+' and '+'spam'+' and '+'eggs'+' and '+'spam'
end2 = time.clock()
print("Time to run + = ", end2 - start2, "seconds")
참고 :이 예제는 Python 3.5로 작성되었습니다. 여기서 range ()는 이전 xrange ()처럼 작동합니다.
내가 얻은 출력 :
Time to run Joiner = 27.086106206103153 seconds
Time to run + = 69.79100515996426 seconds
개인적으로 ''.join ([])은 'Plusser 방식'보다 더 깨끗하고 읽기 쉬우므로 선호합니다.
참조 URL : https://stackoverflow.com/questions/3055477/how-slow-is-pythons-string-concatenation-vs-str-join
'your programing' 카테고리의 다른 글
DateTime.ParseExact ()가 "M / d / yyyy"를 사용하여 "9/1/2009"를 구문 분석 할 수없는 이유 (0) | 2020.12.30 |
---|---|
JavaScript에서 "원시"href 콘텐츠를 얻는 방법 (0) | 2020.12.30 |
끝에 "then"이있는 "if"문의 차이점은 무엇입니까? (0) | 2020.12.30 |
Scala 유형 시스템의 장점 (0) | 2020.12.30 |
YouTube 동영상 ID의 최대 길이는 얼마입니까? (0) | 2020.12.30 |