반응형
목록에 추가하는 것보다 목록 이해가 훨씬 빠른 이유는 무엇입니까?
왜 목록에 추가하는 것보다 목록 이해가 훨씬 빠른지 궁금했습니다.저는 그 차이가 단지 표현적인 것이라고 생각했지만, 그렇지 않습니다.
>>> import timeit
>>> timeit.timeit(stmt='''\
t = []
for i in range(10000):
t.append(i)''', number=10000)
9.467898777974142
>>> timeit.timeit(stmt='t= [i for i in range(10000)]', number=10000)
4.1138417314859
목록 이해 속도가 50% 더 빠릅니다. 왜죠?
목록 이해는 기본적으로 정규 학생들에게 "통사적 설탕"일 뿐입니다.for
루프. 이 경우 더 나은 성능을 발휘하는 이유는 목록의 추가 속성을 로드하고 각 반복 시 함수로 호출할 필요가 없기 때문입니다.즉, 일반적으로 함수의 프레임이나 다른 경우의 여러 함수를 일시 중단했다가 재개하는 것이 요청 시 목록을 만드는 것보다 느리기 때문에 목록 이해가 더 빨리 수행됩니다.
다음 예를 생각해 보십시오.
In [1]: def f1():
...: l = []
...: for i in range(5):
...: l.append(i)
...:
...:
...: def f2():
...: [i for i in range(5)]
...:
In [3]: import dis
In [4]: dis.dis(f1)
2 0 BUILD_LIST 0
2 STORE_FAST 0 (l)
3 4 LOAD_GLOBAL 0 (range)
6 LOAD_CONST 1 (5)
8 CALL_FUNCTION 1
10 GET_ITER
>> 12 FOR_ITER 14 (to 28)
14 STORE_FAST 1 (i)
4 16 LOAD_FAST 0 (l)
18 LOAD_METHOD 1 (append)
20 LOAD_FAST 1 (i)
22 CALL_METHOD 1
24 POP_TOP
26 JUMP_ABSOLUTE 12
>> 28 LOAD_CONST 0 (None)
30 RETURN_VALUE
In [5]:
In [5]: dis.dis(f2)
8 0 LOAD_CONST 1 (<code object <listcomp> at 0x7f397abc0d40, file "<ipython-input-1-45c11e415ee9>", line 8>)
2 LOAD_CONST 2 ('f2.<locals>.<listcomp>')
4 MAKE_FUNCTION 0
6 LOAD_GLOBAL 0 (range)
8 LOAD_CONST 3 (5)
10 CALL_FUNCTION 1
12 GET_ITER
14 CALL_FUNCTION 1
16 POP_TOP
18 LOAD_CONST 0 (None)
20 RETURN_VALUE
Disassembly of <code object <listcomp> at 0x7f397abc0d40, file "<ipython-input-1-45c11e415ee9>", line 8>:
8 0 BUILD_LIST 0
2 LOAD_FAST 0 (.0)
>> 4 FOR_ITER 8 (to 14)
6 STORE_FAST 1 (i)
8 LOAD_FAST 1 (i)
10 LIST_APPEND 2
12 JUMP_ABSOLUTE 4
>> 14 RETURN_VALUE
In [6]:
첫 번째 함수의 오프셋 18에서 볼 수 있습니다.append
목록 이해를 사용하는 두 번째 함수에는 그런 것이 없는 반면 속성.모든 추가 바이트 코드는 추가 접근을 더 느리게 만들 것이고 이 경우에는 로드가 발생하기 때문입니다.append
각 반복에서 속성은 결국 목록 이해만을 사용하여 코드를 두 번째 함수보다 약 두 배 느리게 만듭니다.
검색 및 로드에 소요되는 시간을 고려하는 것도append
함수, 목록은 Python에서 한 번에 하나의 항목을 작성하는 것이 아니라 C로 작성되기 때문에 여전히 목록 이해가 더 빠릅니다.
# Slow
timeit.timeit(stmt='''
for i in range(10000):
t.append(i)''', setup='t=[]', number=10000)
# Faster
timeit.timeit(stmt='''
for i in range(10000):
l(i)''', setup='t=[]; l=t.append', number=10000)
# Faster still
timeit.timeit(stmt='t = [i for i in range(10000)]', number=10000)
언급URL : https://stackoverflow.com/questions/30245397/why-is-a-list-comprehension-so-much-faster-than-appending-to-a-list
반응형
'programing' 카테고리의 다른 글
javadoc for Python 설명서 사용 (0) | 2023.06.10 |
---|---|
SQL Server Reporting Services 보고서에 대체 행 색 추가 (0) | 2023.06.10 |
Apache POI를 사용하여 내 xlsx 시트를 Java 개체로 변환하는 방법 (0) | 2023.06.10 |
데이터 프레임에서 숫자 열만 선택 (0) | 2023.06.10 |
루비: 포함과 반대되는 것이 있습니까?Ruby Arrays의 경우? (0) | 2023.06.05 |