2013-08-16 1 views
0

간단한 작업 인 'list_l에서 x를 제거하십시오.'에 대한 if/then 워크 플로우보다 빠른 워크 플로우가 필요하다고 가정했습니다. 아래 예제에서 예외가 발생할 확률은 시간의 16.6 %이지만 예외 예외 (x는 list_l에 없음)는 권한 요청보다 많습니다 (x가 list_l에있는 경우). 왜?파이썬 속도 테스트 - 왜 예외적 인 실패는 많은 시간을 들여야합니까?

import random, time, timeit 

class Timer(object): 
    def __enter__(self): 
     self.start = time.time() 
     return self 

    def __exit__(self, *args): 
     self.end = time.time() 
     self.secs = self.end - self.start 
     self.msecs = self.secs * 1000 # millisecs 

def a_function(): 
    a_list = list(xrange(10)) 
    choice_list = list(xrange(12)) 
    choice = random.choice(choice_list) 
    try: 
     a_list.remove(choice) 

    except ValueError: 
     pass 

def b_function(): 
    a_list = list(xrange(10)) 
    choice_list = list(xrange(12)) 
    choice = random.choice(choice_list) 
    if choice in a_list: 
     a_list.remove(choice) 

with Timer() as a: 
    print('test_a', timeit.timeit("a_function()", number=10000, setup="from __main__ import a_function")) 

with Timer() as b: 
    print('test_b', timeit.timeit("b_function()", number=10000, setup="from __main__ import b_function")) 

결과 :도

1st attempt: ('test_a', 0.029724836349487305)('test_b', 0.027068138122558594)

2nd attempt: ('test_a', 0.02960801124572754)('test_b', 0.026785850524902344)

3rd attempt: ('test_a', 0.029654979705810547)('test_b', 0.02665996551513672)

, I가 증가하는 경우

여기서 I 부호화 시험과 그 결과는 choice_list 범위를 20으로 설정하면 예외가 더 자주 발생하기 때문에 차이가 넓어집니다. 파이썬이 강력하게 용서가 아닌 허가를 요구한다면, 왜 실패가 시간면에서 비용이 많이 드는 것 같습니까?

+1

시도/캐치는 경우/다음과 같은 구조 (조건부 점프)를 포함해야합니다. 더 많은 일을 처리해야하기 때문에 (오류가 무엇인지 알려주는 것처럼), try/catch는 필자가 직접 테스트하는 것보다 느리게 진행될 것이다. – zebediah49

+0

'타이머'컨텍스트 관리자는 무엇을합니까? 그것은 죽은 코드 인 것처럼 보입니다. 그리고 여러분은 이미'timeit'을 고소하고 있습니다. – delnan

+0

@delnan 처음으로 속도 테스트 코드를 시작했을 때 Timer가 어려웠을 수도 있습니다. 내가 일반적으로하는 일은 단순히 함수를 코드화하는 것뿐입니다. – Cole

답변

6

예외는 모든 언어에서 매우 비싸며 이는 잘못된 사용입니다.

예외는 예외적 인 경우 코드가 계정 할 수없고 정상 작동 중에 올 것으로 예상되지 않는 경우를 의미합니다. 예외적 인 언어에 따라 언어마다 다른 규칙이 있지만 16 %의 시간에 예외적 인 것은 아닙니다.

예외 처리에는 스택 되감기 및 점프, 정상 처리 일시 중지 및 처리기 검색이 포함되므로 비용이 많이 듭니다. 만약 /가 표준이라면, 표준 조건은 효과적이고 명확합니다.

+7

원칙적으로 당신이 동의하는 동안, 파이썬에서는 다른 언어가 if ... then 절을 사용하는 많은 경우에 사용자는 try ... except 구조를 사용하는 것이 좋습니다. 계산 상 효율적이지는 않지만, 예외를 사용하여 특정 유형의 메시지를 호출 스택 위로 전달하는 것이 의미 론적으로 효율적입니다 (Python에서). 특히 파이썬에서 격려 된 "duck-typing"패러다임 때문에 이것이 사실입니다. –

+1

@JoelCornett : 흥미 롭습니다. 나는 파이썬 (나는 루비 녀석)을 많이 모른다. Ruby에는 throw와 catch라는 이름의 특별한 예외 구조가 있습니다. 예외는 정말로 예외적 인 것입니다 (Obj-C의 또 다른 예제). – Linuxios

+2

흥미로운 배경은 다음과 같습니다. http://www.jeffknupp.com/blog/2013/02/06/write-cleaner-python-use-exceptions/ – doctorlove

0

이것은 어두운 부분의 총 찌르기이지만 클래스 기반이고 예외적 인 처리가 순수 로직 기반이기 때문일 수 있습니다. 따라서 통역사는 클래스가 전달할 수있는 것보다 훨씬 단순한 조건부 전달을 최적화 할 수 있습니다. 필요에 의해

http://docs.python.org/release/2.5/whatsnew/pep-352.html

+0

CPython은 그러한 최적화를 수행하지 않습니다. – delnan

관련 문제