Удаление накладных расходов Python при переносе векторов C ++ - PullRequest
0 голосов
/ 08 октября 2018
from libcpp.algorithm cimport sort as stdsort
from libcpp.algorithm cimport unique
from libcpp.vector cimport vector
# from libcpp cimport bool
cimport cython

@cython.boundscheck(False)
@cython.wraparound(False)
@cython.initializedcheck(False)
cdef class Vector:
    cdef vector[cython.int] wrapped_vector

    # the easiest thing to do is add short wrappers for the methods you need
    def push_back(self, int num):
        self.wrapped_vector.push_back(num)

    def sort(self):
        stdsort(self.wrapped_vector.begin(), self.wrapped_vector.end())

    def unique(self):
        self.wrapped_vector.erase(unique(self.wrapped_vector.begin(), self.wrapped_vector.end()), self.wrapped_vector.end())


    def __str__(self):
        return "[" + ", ".join([str(i) for i in self.wrapped_vector]) + "]"

    def __repr__(self):
        return str(self)

    def __len__(self):
        return self.wrapped_vector.size()

    @cython.boundscheck(False)
    @cython.wraparound(False)
    @cython.initializedcheck(False)
    def __setitem__(self, int key, int item):
        self.wrapped_vector[key] = item

    @cython.boundscheck(False)
    @cython.wraparound(False)
    @cython.initializedcheck(False)
    def __getitem__(self, int key):
        return self.wrapped_vector[key]

Я пытался обернуть векторы, чтобы я мог использовать их в Python dicts.

Это, кажется, создает сумасшедшие накладные расходы.Смотрите строки 72 и 75, например.Они просто добавляют целое число к числу уже в векторе:

enter image description here

Возможно ли убрать эти накладные расходы или это цена, которую я плачу за завершениевекторов?

1 Ответ

0 голосов
/ 08 октября 2018

Это, кажется, основано на моем ответе на другой вопрос .Цель добавления __getitem__ и __setitem__ к cdef class Vector заключается в том, чтобы его можно было индексировать из Python.Из Cython вы можете индексировать в вектор C ++ напрямую для дополнительной скорости.

В начале вашего files_to_bins добавьте строку:

cdef Vector v

Это заставит Cython убедиться, что что-нибудьv назначен объект Vector (в противном случае он вызовет TypeError, и, следовательно, вам будет разрешен прямой доступ к его атрибутам cdef.

Затем измените строку:

v[i] = v[i] + half_fragment_size

до:

v.wrapped_vector[i] = v.wrapped_vector[i] + half_fragment_size

(и аналогично для других строк индексации)


Имейте в виду, что boundscheck(False) и wraparound(False) делает абсолютно ничего для объектов C ++.Оператор индексации C ++ не выполняет проверку границ (и Cython не добавляет его), а также не поддерживает отрицательную индексацию.boundscheck и wraparound применяются только для индексирования представлений памяти или массивов.

...