包装C ++向量时消除Python开销 [英] Removing Python overhead when wrapping C++ vectors

查看:83
本文介绍了包装C ++向量时消除Python开销的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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字典中使用它们。

I have tried to wrap vectors so that I can use them in Python dicts.

这似乎会产生大量的开销。例如,参见第72和75行。它们只是向向量中已有的数字添加一个整数:

This seems to create crazy amounts of overhead. See line 72 and 75 for example. They just add an integer to the number already in the vector:

是否可以消除此开销,或者这是我包装矢量所要付出的代价?

Is it possible to remove this overhead or is this the price I pay to wrap vectors?

推荐答案

我对另一个问题的回答为基础。将 __ getitem __ __ setitem __ 添加到 cdef类Vector 纯粹是为了可以从Python进行索引。在Cython中,您可以直接索引C ++向量以提高速度。

This seems to be based on my answer to another question. The purpose of adding __getitem__ and __setitem__ to the cdef class Vector is purely so that it can be indexed from Python. From Cython you can index into the C++ vector directly for extra speed.

files_to_bins 的开头,添加行:

cdef Vector v

这将使Cython确保分配给 v 的任何对象都是 Vector 对象(如果没有,则会引发 TypeError ),因此您将可以直接访问其 cdef 属性。

This will get Cython to make sure that anything assigned to v is a Vector object (it'll raise a TypeError if not) and thus you'll be allowed to access its cdef attributes directly.

然后更改该行:

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 仅适用于索引内存视图或numpy数组。

Be aware that boundscheck(False) and wraparound(False) is doing absolutely nothing for C++ objects. The C++ indexing operator performs no bounds checking (and Cython doesn't add it in) and it does not support negative indexing either. boundscheck and wraparound only apply to indexing memoryviews or numpy arrays.

这篇关于包装C ++向量时消除Python开销的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆