programing

싸이톤에서 리스트/딕트를 하는 관용적인 방법은?

cafebook 2023. 8. 6. 10:21
반응형

싸이톤에서 리스트/딕트를 하는 관용적인 방법은?

내 문제:STL 맵과 벡터를 사용하여 원시 C++로 대용량 데이터 세트를 처리하는 것이 Cython을 사용하는 것보다 훨씬 빠르고 메모리 설치 공간도 적다는 것을 알게 되었습니다.

저는 이 속도 페널티의 일부가 파이썬 목록과 딕트를 사용하기 때문이며, 사이톤에서 방해를 덜 받는 데이터 구조를 사용하기 위한 몇 가지 속임수가 있을 수 있다고 생각합니다.예를 들어, 이 페이지(http://wiki.cython.org/tutorials/numpy) 는 ND 배열의 크기와 유형을 미리 정의하여 Cython에서 numpy 배열을 매우 빠르게 만드는 방법을 보여줍니다.

질문:.목록/딕트와 유사한 작업을 수행할 수 있는 방법이 있습니까? 예를 들어, 목록/딕트에 대략 몇 개의 요소 또는 (키, 값) 쌍이 있을 것으로 예상되는지를 설명하는 방법이 있습니까?즉, Cython에서 목록/딕트를 (빠른) 데이터 구조로 변환하는 관용적인 방법이 있습니까?

그렇지 않다면 C++로 작성하고 사이톤 수입품으로 포장해야 할 것 같습니다.

Cython은 이제 템플릿 지원을 제공하며 일부 STL 컨테이너에 대한 선언이 함께 제공됩니다.

http://docs.cython.org/src/userguide/wrapping_CPlusPlus.html#standard-library 을 참조하십시오.

다음은 그들이 제시한 예입니다.

from libcpp.vector cimport vector

cdef vector[int] vect
cdef int i
for i in range(10):
    vect.push_back(i)
for i in range(10):
    print vect[i]

Python에서 C++에서와 유사한 작업을 수행하는 것은 종종 더 느릴 수 있습니다.list그리고.dict실제로 매우 잘 구현되지만 Python 객체를 사용하면 C++ 객체보다 추상적이고 런타임에 훨씬 더 많은 조회가 필요한 오버헤드를 얻을 수 있습니다.

데그런,,std::vector와 상당히 유사한 방식으로 구현됩니다.list.std::map하지만, 실제로는 많은 작업이 보다 느린 방식으로 구현됩니다.dict크기가 커짐에 따라각각의 적합하게 큰 예에 대해서는,dict보다 느린 상수 요인을 극복합니다.std::map검색, 삽입 등의 작업을 보다 빠르게 수행할 수 있습니다.

당신이 경우용을 사용하고 .std::map그리고.std::vector아무것도 당신을 막지 못합니다.파이썬에 노출시키려면 직접 포장해야 합니다.이 포장이 절약하고자 하는 시간의 전부 또는 많은 시간을 소비하더라도 놀라지 마십시오.이것을 자동으로 해주는 도구가 있는지 모르겠습니다.

개체 생성을 제어하기 위한 C API 호출이 있습니다."최소한 이렇게 많은 요소로 목록 만들기"라고 말할 수 있지만, 이렇게 해도 목록 작성 및 채우기 작업의 전체적인 복잡성이 개선되지 않습니다.나중에 목록을 변경하려고 할 때에는 확실히 변경되지 않습니다.

나의 일반적인 조언은

  • 고정 크기 배열(목록 크기 지정에 대해 설명함)을 원하는 경우 실제로는 numpy 배열과 같은 것을 원할 수 있습니다.

  • 저는 당신이 사용하는 것에서 당신이 원하는 속도를 얻을 수 있을지 의심스럽습니다.std::vector1파운드가 list코드를 대체할 수 있습니다.만약 당신이 그것을 뒤에서 사용하고 싶다면, 그것은 당신에게 만족스러운 크기와 공간을 제공할 것입니다 (물론 측정하지 않고는 저도 모릅니다. ;).

  • dict실제로 그것의 일을 정말 잘합니다.할 수 것입니다.std::map는 많은 알고리즘 더 구현에서는 에게 " 이 많 중 작 알 고 악 적 되 도 일 어 구 사 제 일 게 를 화 공 합 최 다 니 적 부 에 는 leaves 자 용 서 는 에 현 부 은 시 요간적 으 이 한 로 복 ▁which▁to▁optim▁some이▁complex▁the▁that▁has▁worse는다▁userity▁in▁algorithmations니—제—dict이미 있습니다.

    만약 내가 조금 더 효과적인 무언가를 원한다면,std::map데이터베이스를 사용할 겁니다.이것은 일반적으로 내가 저장하고 싶은 물건들이 있을 때 하는 것입니다.dict(또는 그 문제로, 내가 보관하는 물건들.list이 너무 가 너무 커서 메모리에 저장하기가 불편합니다.에는 이썬이 .sqlite3 및 가능한 다른 입니다. stdlib 및 용 .

C++는 벡터와 그 안에 들어가는 요소들의 정적 선언 때문만이 아니라, 결정적으로 템플릿/제너럴을 사용하면 벡터가 특정 유형의 요소들(: 3개의 요소들의 튜플을 가진 벡터)만 포함하도록 지정되기 때문에 빠릅니다.Cython은 이 마지막 일을 할 수 없고 사소한 것처럼 들립니다. 어떻게든 컴파일 시간에 시행되어야 합니다. (런타임에서의 유형 검사는 Python이 이미 수행하고 있는 작업입니다.)그래서 지금 당장 싸이톤의 목록에서 무언가를 꺼낼 때 그것이 어떤 종류인지 미리 알 수 있는 방법은 없습니다. 그리고 그것을 입력된 변수에 넣는 것은 단지 속도가 아니라 유형 검사를 추가할 뿐입니다.이는 이와 관련하여 Python 인터프리터를 우회할 방법이 없다는 것을 의미하며, 비숫자 작업에 대한 Cython의 가장 중요한 단점인 것 같습니다.

이 문제를 해결하는 수동 방법은 python list/dict(또는 std:::vector)를 특정 유형의 요소 또는 키-값 조합에 대한 cdef 클래스로 하위 분류하는 것입니다.이는 템플릿이 생성하는 코드와 동일합니다.Cython 코드에서 결과 클래스를 사용하는 한 개선 사항을 제공해야 합니다.

데이터베이스나 배열을 사용하면 컨테이너에 임의 개체(특정 유형, 가급적이면 acdef 클래스)를 넣는 것이기 때문에 다른 문제를 해결할 수 있습니다.

그리고 std::map은 dict와 비교해서는 안 됩니다. std::map은 균형 트리이기 때문에 정렬된 순서로 키를 유지 관리합니다. dict는 다른 문제를 해결합니다.더 나은 비교는 딕트와 구글의 해시테이블이 될 것입니다.

Python의 표준 모듈이 Cython 설정에 적합한지 확인할 수 있습니다.싸이톤을 사용해 본 적이 없어서 잘 모르겠어요.

네이티브 Python 목록/딕트를 C++ 맵/벡터 또는 그 근처의 속도까지 가져올 수 있는 방법은 없습니다.이는 할당이나 형식 선언과는 관계가 없고 오히려 인터프리터에게 오버헤드를 지불합니다.당신이 언급한 예제(numpy)는 C 확장자이며 정확하게 이러한 이유로 C로 작성되었습니다.

여기에 언급되지 않았기 때문에: 예를 들어 C++ 벡터를 사용자 정의 확장 유형으로 쉽게 래핑할 수 있습니다.

from libcpp.vector cimport vector

cdef class pyvector:
    """Extension type wrapping a vector"""
    cdef vector[long] _data

    cpdef void push_back(self, long x):
        self._data.push_back(x)

    @property
    def data(self):
        return self._data

이러한 방식으로 데이터를 벡터에 저장하여 빠른 Cython 작업을 허용하면서 Python 측에서 (일부 오버헤드로) 데이터에 액세스할 수 있습니다.

언급URL : https://stackoverflow.com/questions/1528691/idiomatic-way-to-do-list-dict-in-cython

반응형