首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在C扩展中使用Python列表

在C扩展中使用Python列表
EN

Stack Overflow用户
提问于 2014-12-26 06:52:28
回答 2查看 172关注 0票数 2

我已经到了需要将类的几个方法重写为C扩展以提高性能的时候(intersection_len,union_len)。我的C语言背景非常有限,而且我从来没有为Python编写过扩展。在扩展中,我需要使用一个list,它是类的一个属性(self.table;它是一个列表和非对象的列表)。扩展名应返回一个整数。因此,问题是,我如何将列表和非对象列表传递给C扩展并在那里读取它?提前谢谢你。

另外,我需要一个自定义哈希表,因为我使用滚动哈希算法,这是谷歌所知道的任何Python模块中都不存在的。

代码语言:javascript
复制
class HashTable:
    def __init__(self, table_length, base):
        self.table_length = table_length
        self.base = base
        self.items = 0
        self.table = [None for _ in xrange(self.table_length)]

    def __iter__(self):
        return iter(self.table)

    def __getitem__(self, hash_value):
        return self.table[hash_value]

    def __len__(self):
        return self.items

    def __str__(self):
        return str(self.table)

    def insert(self, item, hash_value):
        if self.table[hash_value] is None:
            self.table[hash_value] = [item]
            self.items += 1
        else:
            if item not in self.table[hash_value]:
                self.table[hash_value].append(item)
                self.items += 1

    def intersection_len(self, table):
        if table.table_length != self.table_length or table.base != self.base:
            raise ValueError('Tables must have equal length and hash function base')
        result = 0
        for i, items in enumerate(table):
            if items is None or self.table[i] is None:
                continue
            for item in items:
                if item in self.table[i]:
                    result += 1
        return result

    def union_len(self, table):
        if table.table_length != self.table_length or table.base != self.base:
            raise ValueError('Tables must have equal length and hash function base')
        result = 0
        for i in xrange(self.table_length):
            if table[i] is None and self.table[i] is None:
                continue
            elif table[i] is None:
                result += len(self.table[i])
            elif self.table[i] is None:
                result += len(table[i])
            else:
                result += len(table[i])
                for item in table[i]:
                    if item not in self.table[i]:
                        result += 1
        return result

    def dump(self):
        for i in xrange(self.table_length):
            if self.table[i] is not None:
                self.table[i] = None`
EN

回答 2

Stack Overflow用户

发布于 2014-12-26 07:33:34

为什么你相信用C语言重写这个算法会给你带来你想要的性能?(与此版本相比,您对性能的要求是什么?)

我可能会从编写一个性能测试套件开始,然后使用zip而不是嵌套循环(for i in xrange(..))等Python原语来改进Python算法,将CSE从循环中拉出来,等等。

在开始扩展之前,我会在pypy下运行改进的Python版本,以了解您可以从创建C扩展中得到什么。最后,如果需要扩展,我会在使用C之前研究Cython和Boost (因为Python扩展对于C来说是一个相当困难的学习曲线--而且不太可能给您带来运行速度快的东西)。

票数 4
EN

Stack Overflow用户

发布于 2014-12-26 08:00:39

随着列表大小的增加,使用x in some_list的速度会变慢。in操作必须顺序读取列表中的每一项,直到找到匹配项。我会尝试更改您的数据结构,以使用集合列表。

未经测试,但我认为唯一需要更改的代码是insert()

代码语言:javascript
复制
def insert(self, item, hash_value):
    if self.table[hash_value] is None:
        self.table[hash_value] = set()
    self.table[hash_value].add(item)
    self.items += 1
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27651352

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档