解释python中的汉明距离速度

时间:2015-02-04 19:32:54

标签: python runtime timeit hamming-distance

我一直在努力使我的python更加pythonic和玩弄短代码片段的运行时间。我的目标是提高可读性,但另外,还要加快执行速度。

这个例子与我一直在阅读的最佳实践相冲突,我有兴趣找到我思考过程中的缺陷所在。

问题是在两个相等长度的字符串上计算hamming distance。例如,字符串'aaab'和'aaaa'的汉明距离是1。

我能想到的最直接的实现如下:

def hamming_distance_1(s_1, s_2):
    dist = 0
    for x in range(len(s_1)):
        if s_1[x] != s_2[x]:  dist += 1
    return dist

接下来我写了两个“pythonic”实现:

def hamming_distance_2(s_1, s_2): 
    return sum(i.imap(operator.countOf, s_1, s_2))

def hamming_distance_3(s_1, s_2): 
    return sum(i.imap(lambda s: int(s[0]!=s[1]), i.izip(s_1, s_2)))  

执行中:

s_1 = (''.join(random.choice('ABCDEFG') for i in range(10000)))
s_2 = (''.join(random.choice('ABCDEFG') for i in range(10000)))
print 'ham_1  ',  timeit.timeit('hamming_distance_1(s_1, s_2)',  "from __main__ import s_1,s_2, hamming_distance_1",number=1000)
print 'ham_2  ',  timeit.timeit('hamming_distance_2(s_1, s_2)',  "from __main__ import s_1,s_2, hamming_distance_2",number=1000)
print 'ham_3  ',  timeit.timeit('hamming_distance_3(s_1, s_2)',  "from __main__ import s_1,s_2, hamming_distance_3",number=1000)

返回:

ham_1   1.84980392456
ham_2   3.26420593262
ham_3   3.98718094826

我预计ham_3会比ham_2运行得慢,因为调用lambda被视为函数调用,这比调用内置的operator.countOf要慢。

我很惊讶我无法找到一种方法来获得更快的pythonic版本,然后运行得更快。我很难相信ham_1是纯蟒蛇的下限。

有人想到吗?

2 个答案:

答案 0 :(得分:1)

关键是减少方法查找和函数调用:

def hamming_distance_4(s_1, s_2):
    return sum(i != j for i, j in i.izip(s_1, s_2))

在我的系统中ham_4 1.10134792328运行。

ham_2ham_3在循环中查找,因此速度较慢。

答案 1 :(得分:-1)

我想知道在更广泛的意义上,这可能会更像Pythonic。如果您使用http://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.hamming.html ...已经实现了您正在寻找的模块,该怎么办?