TL; DR- 문제 21118
긴 이야기
Josh Rosenberg는 str.translate()
기능이에 비해 매우 느리다는 것을 발견하고 다음 과 bytes.translate
같이 문제 를 제기했습니다 .
Python 3에서 str.translate()
일반적으로 최적화가 아닌 성능 비관적입니다.
왜 str.translate()
느렸습니까?
str.translate()
매우 느린 주된 이유 는 조회가 Python 사전에 있었기 때문입니다.
의 사용은 maketrans
이 문제를 더 악화 시켰습니다. 를 사용하는 유사한 접근 방식 bytes
은 빠른 테이블 조회를 위해 256 개 항목의 C 배열을 구축합니다. 따라서 더 높은 수준의 Python을 dict
사용하면 str.translate()
Python 3.4에서 매우 느려집니다.
이제 무슨 일이 있었습니까?
첫 번째 접근 방식은 작은 패치 인 translate_writer 를 추가하는 것이었지만 속도 증가는 그리 만족스럽지 않았습니다. 곧 또 다른 패치 fast_translate 가 테스트되었고 최대 55 %의 속도 향상이라는 매우 좋은 결과를 얻었습니다.
파일에서 볼 수있는 주요 변경 사항은 Python 사전 조회가 C 레벨 조회로 변경된다는 것입니다.
이제 속도는 다음과 거의 같습니다. bytes
unpatched patched
str.translate 4.55125927699919 0.7898181750006188
str.translate from bytes trans 1.8910855210015143 0.779950579000797
여기서 작은 메모는 성능 향상이 ASCII 문자열에서만 두드러진다는 것입니다.
JFSebastian이 아래 주석 에서 언급했듯이 3.5 이전의 번역은 ASCII 및 비 ASCII 케이스 모두에 대해 동일한 방식으로 작동했습니다. 그러나 3.5 ASCII 케이스에서 훨씬 빠릅니다.
이전의 ASCII와 non-ascii는 거의 동일했지만 이제는 성능에서 큰 변화를 볼 수 있습니다.
이 답변 에서 볼 수 있듯이 71.6μs에서 2.33μs로 개선 될 수 있습니다 .
다음 코드는이를 보여줍니다.
python3.5 -m timeit -s "text = 'mJssissippi'*100; d=dict(J='i')" "text.translate(d)"
100000 loops, best of 3: 2.3 usec per loop
python3.5 -m timeit -s "text = 'm\U0001F602ssissippi'*100; d={'\U0001F602': 'i'}" "text.translate(d)"
10000 loops, best of 3: 117 usec per loop
python3 -m timeit -s "text = 'm\U0001F602ssissippi'*100; d={'\U0001F602': 'i'}" "text.translate(d)"
10000 loops, best of 3: 91.2 usec per loop
python3 -m timeit -s "text = 'mJssissippi'*100; d=dict(J='i')" "text.translate(d)"
10000 loops, best of 3: 101 usec per loop
결과 표 :
Python 3.4 Python 3.5
Ascii 91.2 2.3
Unicode 101 117
dict.fromkeys(ord(c) for c in '@#$')
않을까요?