[]가 list()보다 빠른 이유는 무엇입니까?
최근 처리속도를 비교했습니다.[]
★★★★★★★★★★★★★★★★★」list()
요, ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★.[]
보다 3배 이상 빨리 달리다list()
. . .은테 . . . . . . . . . . . . . . . 。{}
★★★★★★★★★★★★★★★★★」dict()
같았습니다.[]
★★★★★★★★★★★★★★★★★」{}
다 0. 사이클이 , 둘다 초 0.128초/백만 사이클이 소요되었습니다.list()
★★★★★★★★★★★★★★★★★」dict()
각각 약 0.428초/백만 사이클이 소요되었습니다.
왜 ? 하하?[]
★★★★★★★★★★★★★★★★★」{}
(아마도)()
★★★★★★★★★★★★★★★★★」''
는, 으로 이름이 붙여진 상대으)가 있는 동안, 빈 .list()
,dict()
,tuple()
,str()
실제 요소가 있는지 여부에 관계없이 오브젝트 작성에 만전을 기하고 있습니다.
이 두 가지 방법이 어떻게 다른지 모르겠지만 알고 싶습니다.문서나 SO에서 답을 찾을 수 없었고, 빈 괄호를 검색하는 것은 생각보다 문제가 많았습니다.
전화를 해서 타이밍 결과를 얻었습니다.timeit.timeit("[]")
★★★★★★★★★★★★★★★★★」timeit.timeit("list()")
, , , , 입니다.timeit.timeit("{}")
★★★★★★★★★★★★★★★★★」timeit.timeit("dict()")
목록과 사전을 각각 비교합니다.Python 2.7.9입니다.
최근에 발견한 것은 "Why is if True is low than if 1"로 퍼포먼스를 비교한 것입니다.if True
로로 합니다.if 1
, 같은 문자 시나리오에 도 언급하고 있는 것고려해 볼 가 있을지도 모릅니다.을 사용하다
★★★★★★★★★★★★★★★★★★[]
★★★★★★★★★★★★★★★★★」{}
는 리터럴 구문입니다.Python은 목록 또는 사전 개체를 만들기 위해 바이트 코드를 만들 수 있습니다.
>>> import dis
>>> dis.dis(compile('[]', '', 'eval'))
1 0 BUILD_LIST 0
3 RETURN_VALUE
>>> dis.dis(compile('{}', '', 'eval'))
1 0 BUILD_MAP 0
3 RETURN_VALUE
list()
★★★★★★★★★★★★★★★★★」dict()
는 개별 객체입니다.이러한 이름은 해결되어야 하며, 인수를 푸시하기 위해 스택이 관여해야 하며, 나중에 취득하기 위해 프레임을 저장해야 하며, 콜을 해야 합니다.그 모든 것은 시간이 더 걸린다.
빈 케이스의 경우 적어도a(글로벌네임스페이스와 모듈을 통해 검색해야 함)가 있고, 그 뒤에가 이어지므로 현재 프레임을 유지할 필요가 있습니다.
>>> dis.dis(compile('list()', '', 'eval'))
1 0 LOAD_NAME 0 (list)
3 CALL_FUNCTION 0
6 RETURN_VALUE
>>> dis.dis(compile('dict()', '', 'eval'))
1 0 LOAD_NAME 0 (dict)
3 CALL_FUNCTION 0
6 RETURN_VALUE
를 사용하여 이름 검색 시간을 따로 설정할 수 있습니다.
>>> import timeit
>>> timeit.timeit('list', number=10**7)
0.30749011039733887
>>> timeit.timeit('dict', number=10**7)
0.4215109348297119
시간 차이가 사전 해시 충돌일 수 있습니다.이러한 오브젝트를 호출한 시간에서 해당 시간을 뺀 후 결과를 리터럴을 사용한 시간과 비교합니다.
>>> timeit.timeit('[]', number=10**7)
0.30478692054748535
>>> timeit.timeit('{}', number=10**7)
0.31482696533203125
>>> timeit.timeit('list()', number=10**7)
0.9991960525512695
>>> timeit.timeit('dict()', number=10**7)
1.0200958251953125
호출이 합니다.1.00 - 0.31 - 0.30 == 0.39
1000달러
할 수 .timeit
: ,, 、 ,setup 、 이 setup 、 setup setup setup setup setup setup 。
>>> timeit.timeit('_list', '_list = list', number=10**7)
0.1866450309753418
>>> timeit.timeit('_dict', '_dict = dict', number=10**7)
0.19016098976135254
>>> timeit.timeit('_list()', '_list = list', number=10**7)
0.841480016708374
>>> timeit.timeit('_dict()', '_dict = dict', number=10**7)
0.7233691215515137
그 일을 할 수 .CALL_FUNCTION
discloss.discloss.
list()
하지만, 「」는 「」입니다.[]
이치노
Python 2.7.3
>>> import dis
>>> dis.dis(lambda: list())
1 0 LOAD_GLOBAL 0 (list)
3 CALL_FUNCTION 0
6 RETURN_VALUE
>>> dis.dis(lambda: [])
1 0 BUILD_LIST 0
3 RETURN_VALUE
★★★★★★★★★★★★★★★★★★list
say 문자열을 목록 객체로 변환하는 함수입니다.[]
즉석에서 목록을 작성하는 데 사용됩니다.이것을 시험해 보세요(더 이해하기 쉬울 수도 있습니다).
x = "wham bam"
a = list(x)
>>> a
["w", "h", "a", "m", ...]
하는 동안에
y = ["wham bam"]
>>> y
["wham bam"]
입력한 내용이 포함된 실제 목록을 제공합니다.
이 질문에 대한 답변은 훌륭하고 요령 있게 잘 들어맞습니다.관심 있는 분들을 위해 바이트 코드에서 한 단계 더 내려갑니다.CPython의 최신 repo를 사용하고 있습니다.이전 버전도 비슷한 동작을 하지만 약간의 변경이 있을 수 있습니다.
각각의 실행 여기각 here here 、 여기 、 여 here 、 here here here here 。BUILD_LIST
★★★★★★에[]
★★★★★★★★★★★★★★★★★」CALL_FUNCTION
★★★★★★에list()
.
BUILD_LIST
명령:순서:
당신은 공포를 봐야만 해요.
PyObject *list = PyList_New(oparg);
if (list == NULL)
goto error;
while (--oparg >= 0) {
PyObject *item = POP();
PyList_SET_ITEM(list, oparg, item);
}
PUSH(list);
DISPATCH();
끔찍하게 복잡하다는 거 알아심플한 것은 다음과 같습니다.
- 를 사용하여 새 목록을 만듭니다(주로 새 목록 개체에 메모리를 할당합니다).
oparg
스택에 인수의 개수. 7.스택 상의 인수수를 시그널링합니다.이어지는 스트레이틀바로 요점만 말씀하세요. - 잘못된 게 없다고에문제가 없는지 확인합니다와 함께 갔다 확인하십시오.
if (list==NULL)
- (매크로)를 사용하여 스택에 있는 인수(이 경우 실행되지 않음)를 추가합니다.
어쩐지 빠르네요!새로운 리스트를 작성하기 위해서 커스터마이즈 되어 있습니다.다른 것은 없습니다.
그 그CALL_FUNCTION
명령:순서:
이건 암호를에서 다음은을 살짝 엿보기도 당신은 맨 먼저 볼 수 있는 코드 처리 방법을 보면 가장 먼저 볼 수 있는 부분입니다 있다.CALL_FUNCTION
:
PyObject **sp, *res;
sp = stack_pointer;
res = call_function(&sp, oparg, NULL);
stack_pointer = sp;
PUSH(res);
if (res == NULL) {
goto error;
}
DISPATCH();
꽤 해롭지 않아 보이지?아니, 불행히도 그렇지 않아 바로 호출할 사람은 아니지만 그럴 수는 없어대신 스택에서 오브젝트를 취득하고 스택의 모든 인수를 취득한 후 오브젝트의 유형에 따라 전환합니다.
- 아니
PyCFunction_Type
, 그렇지 않아list
,list
있지 형식의 타입이 아니다PyCFunction
- 아니요, 이전을 참조하십시오
PyMethodType
. - 아니
PyFunctionType
, 아까를 봐
우리는 우리는에게 전화하고 있어 전화하고 있다list
형식, 주장,전달된 인수를 입력할 지나갔다.call_function
는 입니다.CPython은 범용 함수를 호출하여 콜 가능한 오브젝트, yay more function 콜을 처리해야 합니다.
이 함수는 다시 특정 함수유형을 체크하고(이유는 이해할 수 없습니다), 필요에 따라 kwargs의 딕트를 작성한 후 콜로 넘어갑니다.
_PyObject_FastCallDict
드디어 우릴 어딘가로 데려왔군!더 많은 체크를 수행한 후 슬롯을 로부터 잡습니다.type
우리는 그렇우리는 통과했다를 잡는다 즉,그것은 붙잡는다 통과했어요.type.tp_call
있다. 그리고 인수를 사용그런 다음태플을 만듭니다 인수로함께 전달된 와가 발표된 투플을 만들기 위해 진행된다._PyStack_AsTuple
드디어 전화가 걸려온다!
tp_call
일치하여 목록개체가 생성됩니다.리스트가 호출됩니다.__new__
대응하여 메모리를 할당합니다.이것이, 최종적으로 따라잡는 부분입니다.위의 모든 항목은 일반적인 방식으로 개체를 처리하기 위해 필요합니다.
결국 마침내.type_call
전화 콜list.__init__
그리고 사용 가능한 인수를 사용하여 목록을 초기화한다면 우리는 돌아오는 등에. 우리가 왔던 길을 간다:-)사용 가능한 인수를 사용하여 목록을 초기화하고 다시 원래대로 돌아갑니다.:-)
마침내, 마지막으로사항을 기억해주세요 다음 remmeber.LOAD_NAME
여기에서 기여하게 되면, 또 다른 남자.여기에도 기여하는 사람이 있어요
이것은 우리의 도움을 다루는 해서 사실상 적절한 Python은 우리의 입력을 처리할 때 실제로 적절한 정보를 찾기 위해 일반적으로 후프를 통과해야 한다는 것을 쉽게 알 수 있습니다를 찾는 데, 파이선 일반적으로 링을 뛰어 넘어야만 해 보는 것은 쉽습니다.C
기능은 일을 하기 위해기능을 합니다. 하는 을 쓸 수도 . 을 사용법list
(그리고 소년은 많은 사람들을 그렇게 한다) 그리고 다른 길을 택해야 한다.
여기가 바로 그 장소입니다list()
많은것을 잃는다: .탐사하는 파이톤은 도대체 무엇을 해야 하는지 알아내기 위해 해야 할 필요가 있다.
한편, 리터럴 구문은 정확하게1가지 의미를 가집니다.변경할 수 없고 항상 사전에 정해진 방식으로 동작합니다.
각주:모든 기능명은 릴리즈마다 변경될 수 있습니다.이 점은 여전히 유효하며, 향후 어떤 버전에서도 유효할 것으로 생각됩니다.동적인 룩업으로 인해 속도가 느려집니다.
?는 왜?
[]
list()
큰 는 Python이 Python을 취급하기 입니다.list()
함수와 로, 다른 수 .list
뭔가 다른 것을 할 수 있습니다(예를 들어, 자신의 서브클래스 리스트나 디큐를 사용합니다).
즉시 삽입 의 새 됩니다.[]
.
내 설명은 이것에 대한 직감을 주기 위한 것이다.
설명.
[]
는 보통 리터럴 구문이라고 불립니다.
문법에서는 이것을 "목록 표시"라고 부릅니다.문서에서:
목록 표시는 대괄호로 둘러싸인 빈 일련의 식입니다.
list_display ::= "[" [starred_list | comprehension] "]"
목록 표시는 새로운 목록 객체를 생성하며, 내용은 식 목록 또는 이해 목록 중 하나로 지정됩니다.쉼표로 구분된 식 목록이 제공되면 해당 요소가 왼쪽에서 오른쪽으로 평가되고 해당 순서대로 목록 개체에 배치됩니다.이해가 제공될 때, 목록은 이해에 따른 요소로 구성됩니다.
타입 「」의 가 「」라고 하는 입니다.list
성됩니니다다
이것을 회피할 수 있는 것은 없습니다.즉, 파이톤은 가능한 한 빨리 그것을 할 수 있습니다.
반,는list()
할 수 있습니다.list
기본 제공 목록 생성자를 사용합니다.
예를 들어, 목록을 노이즈로 생성하려고 합니다.
class List(list):
def __init__(self, iterable=None):
if iterable is None:
super().__init__()
else:
super().__init__(iterable)
print('List initialized.')
후, 「」의 이름을 할 수 .list
에 「」를 하면, 「」라고 하는 것이 됩니다.list
이치노
>>> list = List
>>> a_list = list()
List initialized.
>>> type(a_list)
<class '__main__.List'>
마찬가지로 글로벌 네임스페이스에서 삭제할 수 있습니다.
del list
내장된 네임스페이스에 저장합니다.
import builtins
builtins.list = List
그리고 지금:
>>> list_0 = list()
List initialized.
>>> type(list_0)
<class '__main__.List'>
목록 표시는 무조건 목록을 만듭니다.
>>> list_1 = []
>>> type(list_1)
<class 'list'>
으로만 할 수 있기 것을 해 주세요.★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★List
★★★★★★★★★★★★★★★★★★:
>>> del builtins.list
>>> builtins.list
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: module 'builtins' has no attribute 'list'
>>> list()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'list' is not defined
오, 아뇨, 원본을 잃어버렸어요.
걱정 마, 우린 아직 할 수 있어list
- 리스트 리터럴 타입입니다.
>>> builtins.list = type([])
>>> list()
[]
그래서...
?는 왜?
[]
list()
설명한 바와 같이, 는 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★를 덮어쓸 수 있습니다.list
리터럴 타입의 작성은 대행 수신할 수 없습니다.★★★★★★를 사용하는 경우list
뭐가 있는지 찾아봐야 해요.
그럼 조회한 콜러블을 불러야겠네요문법부터:
전화가 인수 가능성이 있는 빈 시리즈로:호출 가능 개체(예를 들어, 함수는)라고 부른다.
call ::= primary "(" [argument_list [","] | comprehension] ")"
우리는 이것을 어떠한 이름을, 똑같은지 않습니다. 볼 수 있다.
>>> import dis
>>> dis.dis('list()')
1 0 LOAD_NAME 0 (list)
2 CALL_FUNCTION 0
4 RETURN_VALUE
>>> dis.dis('doesnotexist()')
1 0 LOAD_NAME 0 (doesnotexist)
2 CALL_FUNCTION 0
4 RETURN_VALUE
★★★의 []
없는 기능은 파이썬 변경 수준에서를 있다.
>>> dis.dis('[]')
1 0 BUILD_LIST 0
2 RETURN_VALUE
그것은 단순히 직선 어떤 조회 없이 목록을 만들어 내기 위해 또는 바이트 코드 수준에서라고 소리 친다.
결론
우리는 보여 주었다list
는, 코드로 대행 할 수 또, 「스케이핑」, 「스케이핑」, 「스케이핑」, 「스케이핑」, 「스케이핑」, 「스케이핑」, 「스케이핑」, 「스케이핑」, 「스케이핑」, 「스케이프」를 합니다.list()
네, 네, 네, 네.
반에 whereas whereas.[]
는 목록 표시 또는 리터럴이므로 이름 검색 및 함수 호출을 회피합니다.
언급URL : https://stackoverflow.com/questions/30216000/why-is-faster-than-list
'programing' 카테고리의 다른 글
Python 클래스의 동등성("equality")을 지원하는 우아한 방법 (0) | 2022.09.24 |
---|---|
번식 가능한 좋은 판다를 만드는 방법 (0) | 2022.09.24 |
@autowed bean은 다른 bean의 컨스트럭터에서 참조되는 경우 null입니다. (0) | 2022.09.24 |
set Timeout 리셋 (0) | 2022.09.24 |
컴파일 시 함수 파라미터 수 계산 (0) | 2022.09.24 |