복붙노트

[PYTHON] 1 억 개의 0을 가진 효율적인 파이썬 배열?

PYTHON

1 억 개의 0을 가진 효율적인 파이썬 배열?

파이썬에서 대형 배열의 요소를 초기화하고 액세스하는 효율적인 방법은 무엇입니까?

파이썬에서 1 억 개의 엔트리 (부호없는 4 바이트 정수)로 배열을 만들고 싶습니다. 0으로 초기화됩니다. 가급적 인접 메모리를 사용하여 빠른 배열 액세스를 원합니다.

이상하게도, NumPy 배열은 매우 느리게 수행되는 것 같습니다. 시도 할 수있는 대안이 있습니까?

array.array 모듈이 있지만 1 억 개의 블록을 효율적으로 할당하는 방법은 없습니다.

의견에 대한 답변 :

해결법

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

    1.필자는 프로파일 링을 몇 번했는데 그 결과는 완전히 반 직관적입니다. 간단한 배열 액세스 조작의 경우 numpy 및 array.array는 원시 Python 배열보다 10 배 느립니다.

    필자는 프로파일 링을 몇 번했는데 그 결과는 완전히 반 직관적입니다. 간단한 배열 액세스 조작의 경우 numpy 및 array.array는 원시 Python 배열보다 10 배 느립니다.

    배열 액세스의 경우 다음 형식의 연산을 수행합니다.

    a[i] += 1
    

    프로필 :

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

    2.파이썬의 정수가 어떻게 작용 하는지를 상기시켜줍니다.

    파이썬의 정수가 어떻게 작용 하는지를 상기시켜줍니다.

    a = [0] * K
    

    리스트 (sizeof (PyListObject) + K * sizeof (PyObject *))에 대한 메모리와 단일 정수 객체 0에 대한 메모리가 필요하다. 목록의 숫자가 파이썬이 캐싱에 사용하는 매직 넘버 V , 그것들은 공유되어 있기 때문에 괜찮습니다. 즉, n

    >>> i = 0
    >>> j = 0
    >>> while i is j:
    ...    i += 1
    ...    j += 1
    >>> i # on my system!
    257 
    

    이는 카운트가이 숫자보다 커지면 sizeof (PyListObject) + K * sizeof (PyObject *) + d * sizeof (PyIntObject)가되는 것을 의미합니다. 여기서 d

    numpy.ndarray 또는 array.array를 사용하면 초기화 후에도 메모리 사용량이 일정하지만 Thomas Wouters가 말한 것처럼 투명하게 작성된 래퍼 객체에 대해서는 비용을 지불해야합니다. 아마도 Cython이나 scipy.weave를 사용하여 업데이트 코드 (배열의 위치를 ​​액세스하고 증가시키는)를 C ​​코드로 변환하는 것에 대해 생각해야합니다.

  3. ==============================

    3.이 시도:

    이 시도:

    x = [0] * 100000000
    

    내 컴퓨터에서 실행하는 데 몇 초 정도 걸리며 즉시 액세스 할 수 있습니다.

  4. ==============================

    4.계산을 벡터화 할 수 없다면 Python / Numpy가 느려질 것입니다. Numpy는 벡터화 된 계산이 파이썬보다 낮은 레벨에서 발생하기 때문에 빠릅니다. 핵심 numpy 함수는 모두 C 또는 Fortran으로 작성됩니다. 따라서 sum (a)은 많은 액세스를 가진 파이썬 루프가 아니며 하나의 하위 레벨 C 호출입니다.

    계산을 벡터화 할 수 없다면 Python / Numpy가 느려질 것입니다. Numpy는 벡터화 된 계산이 파이썬보다 낮은 레벨에서 발생하기 때문에 빠릅니다. 핵심 numpy 함수는 모두 C 또는 Fortran으로 작성됩니다. 따라서 sum (a)은 많은 액세스를 가진 파이썬 루프가 아니며 하나의 하위 레벨 C 호출입니다.

    Numpy의 Performance Python 데모 페이지에는 다양한 옵션이있는 좋은 예가 있습니다. 가능하다면 낮은 수준의 컴파일 된 언어 인 Cython을 사용하거나 벡터화 된 함수를 사용하면 쉽게 100 배 증가 할 수 있습니다. 이 블로그 게시물은 Cython을 사용하여 numpy 유스 케이스에 43 배 증가한 것을 보여줍니다.

  5. ==============================

    5.당신이 numpy의 배열보다 빠른 것을 발견 할 것 같지는 않습니다. 배열 자체의 구현은 C와 마찬가지로 효율적입니다 (기본적으로 array.array와 동일하지만 더 유용합니다).

    당신이 numpy의 배열보다 빠른 것을 발견 할 것 같지는 않습니다. 배열 자체의 구현은 C와 마찬가지로 효율적입니다 (기본적으로 array.array와 동일하지만 더 유용합니다).

    코드 속도를 높이려면 코드를 실행해야합니다. 배열이 효율적으로 구현 되더라도 Python 코드에서 액세스하면 특정 오버 헤드가 발생합니다. 예를 들어, 배열을 인덱싱하면 정수 객체가 생성됩니다. 정수 객체는 즉석에서 만들어야합니다. numpy는 C에서 효율적으로 구현되는 여러 가지 작업을 제공하지만 특정 코드를 제안하기가 어렵 기 때문에 실적이 좋지 않은 실제 코드를 보지 않아도됩니다.

  6. ==============================

    6.빠른 생성을 위해서는 어레이 모듈을 사용하십시오.

    빠른 생성을 위해서는 어레이 모듈을 사용하십시오.

    어레이 모듈을 사용할 때 생성 속도는 약 5 배 빠르지 만 일반 목록과 비교할 때 요소에 액세스하는 속도는 약 두 배입니다.

    # Create array
    python -m timeit -s "from array import array" "a = array('I', '\x00'
     * 100000000)"
    10 loops, best of 3: 204 msec per loop
    
    # Access array
    python -m timeit -s "from array import array; a = array('I', '\x00'
    * 100000000)" "a[4975563]"
    10000000 loops, best of 3: 0.0902 usec per loop
    
    # Create list
    python -m timeit "a = [0] * 100000000"
    10 loops, best of 3: 949 msec per loop
    
    # Access list
    python -m timeit  -s "a = [0] * 100000000" "a[4975563]"
    10000000 loops, best of 3: 0.0417 usec per loop
    
  7. ==============================

    7.다른 훌륭한 솔루션 외에도 또 다른 방법은 배열 대신 사전을 사용하는 것입니다 (존재하는 요소는 0이 아니며, 그렇지 않으면 0입니다). 조회 시간은 O (1)입니다.

    다른 훌륭한 솔루션 외에도 또 다른 방법은 배열 대신 사전을 사용하는 것입니다 (존재하는 요소는 0이 아니며, 그렇지 않으면 0입니다). 조회 시간은 O (1)입니다.

    응용 프로그램이 스왑 아웃 대신 RAM에 상주하는지 확인할 수도 있습니다. 381MB에 불과하지만 시스템이 어떤 이유에서든 제공하지 않을 수 있습니다.

    그러나 정말 빠른 스파 스 매트릭스 (SciPy 및 ndsparse)도 있습니다. 그들은 저수준 C에서 행해지 며 또한 좋을 수도 있습니다.

  8. ==============================

    8.난 단순히 모든 값을 초기화하지 않는 자신의 데이터 형식을 만들 것입니다.

    난 단순히 모든 값을 초기화하지 않는 자신의 데이터 형식을 만들 것입니다.

    아직 초기화되지 않은 인덱스 위치를 읽으려면 0을 반환합니다. 여전히 저장소를 초기화하지 마십시오.

    HAS가 초기화 된 색인 위치를 읽으려면 값을 리턴하십시오.

    아직 초기화되지 않은 인덱스 위치에 쓰고 싶으면 초기화하고 입력을 저장하십시오.

  9. ==============================

    9.NumPy는 크기가 크고 고정 크기 인 균질 배열에 적합한 도구입니다. 파이썬에서 개별 요소를 액세스하는 것은 그렇게 빠르지는 않을 것입니다. 그러나 전체 배열 연산은 종종 C 나 포트란과 비슷한 속도로 수행 될 수 있습니다. 수백만, 수백만 개의 요소를 개별적으로 신속하게 처리해야하는 경우 파이썬에서 벗어날 수있는 부분이 많습니다.

    NumPy는 크기가 크고 고정 크기 인 균질 배열에 적합한 도구입니다. 파이썬에서 개별 요소를 액세스하는 것은 그렇게 빠르지는 않을 것입니다. 그러나 전체 배열 연산은 종종 C 나 포트란과 비슷한 속도로 수행 될 수 있습니다. 수백만, 수백만 개의 요소를 개별적으로 신속하게 처리해야하는 경우 파이썬에서 벗어날 수있는 부분이 많습니다.

    어떤 종류의 알고리즘을 구현하고 있습니까? 스파 스 어레이를 사용하지 않았다면 너무 느리다는 것을 어떻게 알 수 있습니까? "효율적인"이란 무엇을 의미합니까? 빠른 초기화가 필요하십니까? 그것은 코드의 병목 현상입니까?

  10. ==============================

    10.만약

    만약

    다음 사항이 귀하에게 중요 할 수 있습니다. 그것은 array.array ( 'L', [0] * size)보다 약 27 배 더 빠르게 array.array를 초기화합니다.

    myarray = array.array('L')
    f = open('/dev/zero', 'rb')
    myarray.fromfile(f, size)
    f.close()
    

    어떻게 파이썬에서 정수 array.array 객체를 0으로 초기화 하는가? 나는 더 좋은 방법을 찾고있다.

  11. from https://stackoverflow.com/questions/2214651/efficient-python-array-with-100-million-zeros by cc-by-sa and MIT license