Python의 예외 처리기 비용
다른 질문에서 수락된 답변은 성능을 향상시키기 위해 Python 코드의 if 문을 try/except 블록으로 교체하는 것을 제안했습니다.
코딩 스타일 문제는 차치하고, 예외가 트리거되지 않는다고 가정하면 예외 핸들러가 없는 것과 if-statement가 0과 비교하여 (성능 측면에서) 얼마나 차이가 있습니까?
모듈을 사용하여 측정해 보는 것이 어떻습니까?이렇게 하면 응용 프로그램과 관련이 있는지 확인할 수 있습니다.
좋습니다. 방금 다음을 시도했습니다(Windows 11에서 Python 3.11.1 사용).
import timeit
statements=["""\
try:
b = 10/a
except ZeroDivisionError:
pass""",
"""\
if a:
b = 10/a""",
"b = 10/a"]
for a in (1,0):
for s in statements:
t = timeit.Timer(stmt=s, setup='a={}'.format(a))
print("a = {}\n{}".format(a,s))
print("%.2f usec/pass\n" % (1000000 * t.timeit(number=100000)/100000))
결과:
a = 1
try:
b = 10/a
except ZeroDivisionError:
pass
0.06 usec/pass
a = 1
if a:
b = 10/a
0.05 usec/pass
a = 1
b = 10/a
0.03 usec/pass
a = 0
try:
b = 10/a
except ZeroDivisionError:
pass
0.27 usec/pass
a = 0
if a:
b = 10/a
0.02 usec/pass
a = 0
b = 10/a
Traceback (most recent call last):
File "<stdin>", line 5, in <module>
File "C:\Python311\Lib\timeit.py", line 178, in timeit
timing = self.inner(it, self.timer)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<timeit-src>", line 6, in inner
ZeroDivisionError: division by zero
보다시피, 사용하는 것 사이에는 큰 차이가 없습니다.try/except
조항 대 명시적 조항if
예외가 트리거되지 않는 한 명령문을 사용할 수 있습니다. (물론 제어 구조가 없는 것이 가장 빠르며, 크게는 아니지만, 잘못되면 프로그램이 중단됩니다.)
이를 2010년에 얻은 결과와 비교해 보십시오.
a = 1
try:
b = 10/a
except ZeroDivisionError:
pass
0.25 usec/pass
a = 1
if a:
b = 10/a
0.29 usec/pass
a = 1
b = 10/a
0.22 usec/pass
a = 0
try:
b = 10/a
except ZeroDivisionError:
pass
0.57 usec/pass
a = 0
if a:
b = 10/a
0.04 usec/pass
a = 0
b = 10/a
ZeroDivisionError: int division or modulo by zero
제가 지금 사용하는 PC는 그 당시의 PC보다 두 배 정도 빠른 것 같습니다.예외를 처리하는 비용은 동일한 것으로 보이며 "정상" 연산(산술)은 제어 구조를 처리하는 것보다 훨씬 더 개선되었지만, 수년 전의 요점은 여전히 다음과 같습니다.
모든 것이 같은 크기의 순서 내에 있으며 어느 쪽이든 상관없을 것 같습니다.조건이 실제로 충족되는 경우에만(자주),if
버전이 훨씬 빠릅니다.
이 질문은 실제로 설계 및 기록 FAQ에 답변되어 있습니다.
예외가 발생하지 않는 경우 시도/제외 블록이 매우 효율적입니다.실제로 예외를 잡는 것은 비용이 많이 듭니다.
Python 3.11에서는
“Zero-cost” exceptions are implemented. The cost of try statements is almost eliminated when no exception is raised. (Contributed by Mark Shannon in bpo-40222.)
https://docs.python.org/3.11/whatsnew/3.11.html#optimizations
이 질문은 오해의 소지가 있습니다.예외가 트리거되지 않는다고 가정하면 둘 다 최적의 코드가 아닙니다.
예외가 오류 조건의 일부로 트리거된다고 가정하면, 이미 최적의 코드를 원하는 범위를 벗어난 것입니다(그리고 아마도 그렇게 세부적인 수준에서 처리하지는 않을 것입니다)
Pythonic의 "허락이 아닌 용서를 구하라"는 표준 제어 흐름의 일부로 예외를 사용하는 경우 예외가 트리거되며, 비용은 예외의 종류, 발생 여부 및 발생 시간의 비율에 따라 달라집니다.
Q: 그렇습니까?try/catch
파이썬이 비싸다고요?
트라이 캐치를 사용할 때 주의해야 합니까?어떤 식으로?
이것은 이미 제공된 답변의 요약일 뿐입니다.
A: 예외가 있을 때if
훨씬 빠릅니다.그렇지 않으면 안 됩니다.
@SuperNova는 예외가 제로 비용이므로 예외가 없을 때 if-statement를 갖는 것보다 더 빠르다고 쓰고 있습니다.그러나 예외를 처리하는 데는 비용이 많이 들기 때문에 다음과 같습니다.
실패할 수 있는 것들을 시도해 보세요.가능하면 실패할 것을 알고 시도하지 마십시오.
예:
- 좋은 경우입니다. try:
try:
x = getdata() # an external function
except:
print('failed. Retrying')
- 잘못된 경우. 여기서 if-version이 선호됩니다.
y = f(x) # f never fails but often returns 0
try:
z = 1 / y # this fails often
except:
print('failed.')
# if-version
y = f(x)
if y != 0:
z = 1 / y
else:
print('failed.')
언급URL : https://stackoverflow.com/questions/2522005/cost-of-exception-handlers-in-python
'programing' 카테고리의 다른 글
잠금을 시도할 때 교착 상태가 발견되지 않도록 합니다. 중복 키 업데이트 시 MariaDB(MySQL) INSERT에서 트랜잭션을 다시 시작해 보십시오. (0) | 2023.08.20 |
---|---|
NSTime에서 변환시간, 분, 초, 밀리초 단위의 swift 간격 (0) | 2023.08.20 |
SQL Server 2008에서 트랜잭션 로그를 보는 방법 (0) | 2023.08.20 |
서비스:렌더러2에 대한 공급자 없음 (0) | 2023.08.20 |
신속한 프로젝트에서 Objective-C 코코아 포드를 사용하는 방법 (0) | 2023.08.20 |