자기개발/개발이야기

파이썬 비교비용 프로파일링 삽질기

친구들과 파이썬 삽질을 하면서 이리저리 많이 알아기에 그를 정리하고 공유하고자 글을 작성한다.

깔끔한 결론따위 없는 삽질기니 기대 없이 이런게 있구나 생각하면서 보는게 좋다.

발단

다음과 같은 코드가 있다.

if x in [long_string, big_string, nagai_string] 

이 코드가 진짜 많이 호출된다고 해보자.

뭔가 최적화 할 방법은 없을까??

어차피 80/20 법칙 그런걸로 이런거 고칠바에는 다른 곳을 고치는게 성능향상에 도움이 되지만, 이러한 삽질은 재밌기에 해봤다.

(실제로 python에서의 문자열 비교는 길이가 같으면 O(1), 길이가 다르면 O(n)이라고 알려져있는 것으로 보이지만, 그렇게 단순하게 생각하기엔 여러 글이 있다. 여기서는 자세히 다루지 않는다. 참고 : http://pit-claudel.fr/clement/blog/modeling-and-measuring-string-comparison-performance-in-c-cpp-csharp-and-python/)

dis.dis를 써서 이리저리 해보는게 기본 아이디어다.

list가 저렇게 있으면 매번 생성 될 것이니 별도 변수로 뺀다.

답 : 별차이 없다.

애초에 매번 생성하질 않고 CONST 취급으로 최적화한다.

이건 별 문제 없다 생각해도 될 것 같다.

list 말고 set 을 쓴다

list는 일반 연산일 것 같은데, set이면 hash 연산으로 좀 더 빠르지 않을까 싶은 생각이 있었다.

set 생성비용이 list보다 더 들지 않을까 했는데, 그건 아닌걸로 보인다.

사실 진짜 hash 연산으로 해줄지도 모르겠다. 애초에 짧은 문자열이면 금방 비교되는것처럼도 보인다.

긴 collection에 긴 문자열이면 좀 빨라질까? 이정도 까지 생각만 하고 더이상 파보는건 그만두었다.

결론

dis.dis는 신이고 나는 우주의 먼지다. 성능 걱정이 조금 있으면 이걸로 슬쩍 분석해보면 이해도가 높아진다.

결국 IN Operator 작동 방식을 알아야 list하고 set을 비교할 수 있을텐데 거기까진 가지 못했다.

timeit까지 쓰면 간단한 점검은 다 하는 것 같다.

애초에 극한의 속도를 신경쓰면 python을 쓰면 안되는거같기도 하다.

이런 이런저런 생각이 들었다.

끝!