我已经到了需要将类的几个方法重写为C扩展以提高性能的时候(intersection_len,union_len)。我的C语言背景非常有限,而且我从来没有为Python编写过扩展。在扩展中,我需要使用一个list,它是类的一个属性(self.table;它是一个列表和非对象的列表)。扩展名应返回一个整数。因此,问题是,我如何将列表和非对象列表传递给C扩展并在那里读取它?提前谢谢你。
另外,我需要一个自定义哈希表,因为我使用滚动哈希算法,这是谷歌所知道的任何Python模块中都不存在的。
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`
发布于 2014-12-26 07:33:34
为什么你相信用C语言重写这个算法会给你带来你想要的性能?(与此版本相比,您对性能的要求是什么?)
我可能会从编写一个性能测试套件开始,然后使用zip
而不是嵌套循环(for i in xrange(..)
)等Python原语来改进Python算法,将CSE从循环中拉出来,等等。
在开始扩展之前,我会在pypy下运行改进的Python版本,以了解您可以从创建C扩展中得到什么。最后,如果需要扩展,我会在使用C之前研究Cython和Boost (因为Python扩展对于C来说是一个相当困难的学习曲线--而且不太可能给您带来运行速度快的东西)。
发布于 2014-12-26 08:00:39
随着列表大小的增加,使用x in some_list
的速度会变慢。in
操作必须顺序读取列表中的每一项,直到找到匹配项。我会尝试更改您的数据结构,以使用集合列表。
未经测试,但我认为唯一需要更改的代码是insert()
。
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
https://stackoverflow.com/questions/27651352
复制相似问题