복붙노트

[PYTHON] 왜 ''.join ()이 파이썬에서 + =보다 빠릅니까?

PYTHON

왜 ''.join ()이 파이썬에서 + =보다 빠릅니까?

파이썬에서 연결에 + 또는 + =를 사용하는 것이 비효율적이고 나쁜 방법 인 이유에 대해 온라인 (스택 오버플로 및 기타)에 정보가 쌓여있는 것을 발견 할 수 있습니다.

나는 왜 그렇게 비효율적인지 알 수 없다. "특정 사례에서 20 %의 개선을 위해 최적화되었습니다"라는 언급을 제외하고 (아직 이러한 사례가 무엇인지 명확하지 않음), 추가 정보를 찾을 수 없습니다.

''.join ()이 다른 파이썬 연결 메소드보다 우수한 기술 수준에서 무슨 일이 일어나고 있습니까?

해결법

  1. ==============================

    1.세 문자열에서 문자열을 작성하는 코드가 있다고 가정 해 보겠습니다.

    세 문자열에서 문자열을 작성하는 코드가 있다고 가정 해 보겠습니다.

    x = 'foo'
    x += 'bar'  # 'foobar'
    x += 'baz'  # 'foobarbaz'
    

    이 경우, 파이썬은 먼저 'foobar'를 할당하고 생성하기 전에 'foobar'를 할당하고 생성해야합니다.

    따라서 각 + =가 호출되면 문자열의 전체 내용과 추가되는 내용이 완전히 새로운 메모리 버퍼에 복사되어야합니다. 즉, N 개의 문자열을 합치려면 약 N 개의 임시 문자열을 할당해야하며 첫 번째 하위 문자열은 ~ N 번 복사됩니다. 마지막 부분 문자열은 한 번만 복사되지만, 평균적으로 각 부분 문자열은 ~ N / 2 번 복사됩니다.

    .join을 사용하면 파이썬은 중간 문자열을 생성 할 필요가 없으므로 여러 가지 트릭을 재생할 수 있습니다. CPython은 얼마나 많은 메모리를 필요로하는지 파악한 다음 정확한 크기의 버퍼를 할당합니다. 마지막으로 각 조각을 새로운 버퍼에 복사합니다. 즉, 각 조각은 한 번만 복사됩니다.

    어떤 경우에는 + =의 성능을 향상시킬 수있는 다른 실행 가능한 접근 방식이 있습니다. 예 : 내부 문자열 표현이 실제로 로프인지 아니면 런타임이 실제로 임시 문자열이 프로그램에 아무 쓸모가 없다는 것을 알기에 충분히 똑똑하고 멀리 떨어져 있다면.

    그러나 CPython은 확실히 이러한 최적화를 안정적으로 수행하지는 않지만 (일부 모서리의 경우에 해당 할지라도) CPython이 가장 일반적으로 사용되기 때문에 CPython에서 잘 작동하는 방법을 기반으로합니다. 표준화 된 표준 집합을 가짐으로써 다른 구현에서도 최적화 노력에 더 쉽게 집중할 수 있습니다.

  2. ==============================

    2.이 동작은 루아의 문자열 버퍼 장에서 가장 잘 설명된다고 생각합니다.

    이 동작은 루아의 문자열 버퍼 장에서 가장 잘 설명된다고 생각합니다.

    파이썬의 문맥에서 그 설명을 다시 쓰기 위해서, 무해한 코드 스 니펫 (Lua의 docs에서 유래 한 것)으로 시작해 보겠습니다 :

    s = ""
    for l in some_list:
      s += l
    

    각 l은 20 바이트이고 s는 이미 50KB의 크기로 파싱되었다고 가정합니다. 파이썬이 s + l을 연결하면 50,020 바이트의 새로운 문자열을 만들고 s에서 50KB를이 새로운 문자열로 복사합니다. 즉, 각 줄마다 프로그램이 50KB의 메모리를 이동하고 확장합니다. 100 줄의 새 행 (2KB 만)을 읽은 후 스 니펫은 이미 5MB 이상의 메모리를 이동했습니다. 상황을 악화 시키려면 과제가 끝난 후

    s += l
    

    오래된 문자열은 이제 쓰레기입니다. 두 개의 루프 사이클 후에 총 100KB의 쓰레기를 만드는 두 개의 오래된 문자열이 있습니다. 그래서 언어 컴파일러는 가비지 컬렉터를 실행하기로 결정하고 그 100KB를 해제합니다. 문제는이 작업이 매 2주기마다 발생하며 전체 목록을 읽기 전에 가비지 수집기를 2,000 번 실행한다는 것입니다. 이 모든 작업을 수행하더라도 메모리 사용량은 목록 크기의 큰 배수가됩니다.

    그리고, 결국 :

    파이썬 문자열은 불변 객체이기도합니다.

  3. from https://stackoverflow.com/questions/39312099/why-is-join-faster-than-in-python by cc-by-sa and MIT license