파이썬에서의 str 성능


88

파이썬 코드의 조각을 프로파일 링하는 동안 ( python 2.6최대 3.2), I는 것을 발견 str문자열로 (내 경우 정수에) 메서드는 개체를 변환하는 것은 느린 서식 문자열을 사용하는 것보다 크기의 거의 순서입니다.

다음은 벤치 마크입니다.

>>> from timeit import Timer
>>> Timer('str(100000)').timeit()
0.3145311339386332
>>> Timer('"%s"%100000').timeit()
0.03803517023435887

왜 이것이 사실인지 아는 사람이 있습니까? 내가 뭔가를 놓치고 있습니까?


2
그리고 '{}'.format(100000)
wim

그것은 가장 느리지 만 가장 유연합니다.
Luca Sbardella

답변:


106

'%s' % 100000 컴파일러에 의해 평가되며 런타임시 상수와 동일합니다.

>>> import dis
>>> dis.dis(lambda: str(100000))
  8           0 LOAD_GLOBAL              0 (str)
              3 LOAD_CONST               1 (100000)
              6 CALL_FUNCTION            1
              9 RETURN_VALUE        
>>> dis.dis(lambda: '%s' % 100000)
  9           0 LOAD_CONST               3 ('100000')
              3 RETURN_VALUE        

%런타임 표현식은 str다음 보다 (상당히) 빠르지 않습니다 .

>>> Timer('str(x)', 'x=100').timeit()
0.25641703605651855
>>> Timer('"%s" % x', 'x=100').timeit()
0.2169809341430664

str@DietrichEpp가 말했듯이 여전히 약간 느리다는 점에 유의하십시오. 이는 str조회 및 함수 호출 작업이 포함되고 %단일 즉각적인 바이트 코드로 컴파일 되기 때문입니다 .

>>> dis.dis(lambda x: str(x))
  9           0 LOAD_GLOBAL              0 (str)
              3 LOAD_FAST                0 (x)
              6 CALL_FUNCTION            1
              9 RETURN_VALUE        
>>> dis.dis(lambda x: '%s' % x)
 10           0 LOAD_CONST               1 ('%s')
              3 LOAD_FAST                0 (x)
              6 BINARY_MODULO       
              7 RETURN_VALUE        

물론 위의 내용은 내가 테스트 한 시스템 (CPython 2.7)에 해당됩니다. 다른 구현은 다를 수 있습니다.


실제로 이것은 이유처럼 보입니다. 방금 직접 시도했으며 문자열 형식화가 str. 대답 해줘서 고마워요. 모든 곳에서 코드를 변경할 이유가 없습니다 :-)
Luca Sbardella

2
더 자세히 설명하자면 : str은 문자열 유형이 아닌 다른 이름으로 리 바인드 할 수 있지만 문자열 형식화 (예 : str.__mod__메소드)는 대체 할 수 없으므로 컴파일러가 최적화를 수행 할 수 있도록합니다. 컴파일러는 최적화 방식에서 그다지 많은 작업을 수행하지 않지만 생각보다 더 많은 작업을 수행합니다. :)
Karl Knechtel

4
... 그리고 여기서 배울 교훈은 : 이런 테스트에서는 절대 리터럴을 사용하지 마세요!
UncleZeiv

이 특정 블로그 항목에 관심이있을 수 있습니다 : skymind.com/~ocrow/python_string . 위에 제공 한 것과 유사한 다양한 문자열 연결 방법에 대한 벤치 마크 차트가 포함되어 있습니다.
Aaron Newton

14

떠오르는 한 가지 이유 str(100000)는 글로벌 조회 를 포함하지만 "%s"%100000그렇지 않은 사실입니다 . str글로벌은 글로벌 범위에서보고되어야한다. 이것은 전체 차이를 설명하지 않습니다.

>>> Timer('str(100000)').timeit()
0.2941889762878418
>>> Timer('x(100000)', 'x=str').timeit()
0.24904918670654297

thg435 에서 언급 했듯이 ,

>>> Timer('"%s"%100000',).timeit()
0.034214019775390625
>>> Timer('"%s"%x','x=100000').timeit()
0.2940788269042969
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.