programing

[]가 list()보다 빠른 이유는 무엇입니까?

procenter 2022. 9. 24. 22:17
반응형

[]가 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.391000달러

할 수 .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_FUNCTIONdiscloss.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        

★★★★★★★★★★★★★★★★★★listsay 문자열을 목록 객체로 변환하는 함수입니다.[]즉석에서 목록을 작성하는 데 사용됩니다.이것을 시험해 보세요(더 이해하기 쉬울 수도 있습니다).

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();

꽤 해롭지 않아 보이지?아니, 불행히도 그렇지 않아 바로 호출할 사람은 아니지만 그럴 수는 없어대신 스택에서 오브젝트를 취득하고 스택의 모든 인수를 취득한 후 오브젝트의 유형에 따라 전환합니다.

우리는 우리는에게 전화하고 있어 전화하고 있다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

반응형