문자열 표현을 1에서 많은 수 (내 경우 20000000)로 연결하여 다른 속도 연결 방법의 속도를 테스트하고 있습니다. 결과 아무튼 나는 순진보다 빠를하는 개선 된 방법을 볼 것으로 예상하고파이썬 문자열 연결 속도
import cProfile
count = 20000000
def profileWrapper(f):
def wrapper(*args, **argv):
pr = cProfile.Profile()
pr.enable()
string = f(*args, **argv)
pr.create_stats()
pr.print_stats()
return string
return wrapper
@profileWrapper
def naiveConcat():
global count
string = ''
for i in xrange(count):
string += `i`
return string
@profileWrapper
def improvedConcat():
global count
string = []
for i in xrange(count):
string.append(`i`)
return ''.join(string)
@profileWrapper
def fastestConcat():
global count
return ''.join([`i` for i in xrange(count)])
print 15 * "=", "naiveConcat", 15 * "="
naiveConcat()
print 15 * "=", "improvedConcat", 15 * "="
improvedConcat()
print 15 * "=", "fastestConcat", 15 * "="
fastestConcat()
, 그것은 '가장 빠른 방법보다 훨씬 느린 안 :하지만, 내가 테스트입니다 세 가지 방법이 있습니다 다음과 같이 보입니다 :
=============== naiveConcat ===============
3 function calls in 3.951 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.000 0.000 cProfile.py:90(create_stats)
1 3.951 3.951 3.951 3.951 str_concat.py:18(naiveConcat)
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
=============== improvedConcat ===============
20000004 function calls in 6.990 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.000 0.000 cProfile.py:90(create_stats)
1 5.196 5.196 6.990 6.990 str_concat.py:26(improvedConcat)
20000000 1.322 0.000 1.322 0.000 {method 'append' of 'list' objects}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
1 0.473 0.473 0.473 0.473 {method 'join' of 'str' objects}
=============== fastestConcat ===============
4 function calls in 3.043 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.000 0.000 cProfile.py:90(create_stats)
1 2.539 2.539 3.043 3.043 str_concat.py:34(fastestConcat)
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
1 0.504 0.504 0.504 0.504 {method 'join' of 'str' objects}
개선 된 방법은 순진한 방법보다 훨씬 느립니다.
순진한 방법이 새로운 바인딩을 생성하고 각 문자열에 연결된 문자열 문자와 함께 이전 문자열을 복사하기 때문에이 방법은 의미가 없습니다.이 방법은 O (n^2) O (n) 인 다른 방법보다 느립니다.
그래서 개선 된 방법이 너무 느립니까? 내가 생각할 수있는 유일한 이유는 append 메서드이지만, this article에 따르면 append 메서드는 O (1)을 사용하므로 명확히 이유가 아닙니다. 그럼 개선 된 콘택()에서 오래 걸리는 것은 무엇입니까? 고맙습니다.
신중해야합니다. "추가"를시기하지만 "결합"에 대한 결과 만 기대합니다. 기본 "% s % s"% (str1, str2) 함수를 사용하십시오. 그것은 대부분의 상황에서 가장 빠릅니다. – cox
@cox, 필자는 연결 함수에서 필요하기 때문에 "추가"를 할 필요가 있습니다. 제안한 방식대로 다른 함수를 작성 했으므로 가장 느린 네 가지 중에서 가장 단순한 방법보다 느립니다. 어쩌면 몇 개의 문자열 만 연결하는 것이 더 빠를 수도 있지만 많은 양의 문자열 세그먼트를 연결하는 경우가 아닙니다. 이 경우 – elgoog
의 경우 "join"이 옵션 일 수 있습니다. 파이썬/C++/... 문자열의 장점은 길이가 객체 속성에 캐시된다는 것입니다. 따라서 기본 연산의 경우 C보다 Python에서 더 나은 결과를 얻을 수 있습니다. 그러나 연결은 또 다른 짐승입니다. 와트는 데이터를 메모리에 할당하거나 채우는 것입니다. 유형은 적합하지 않습니다. 아마도 cython 함수가 더 빠를 것입니까? – cox