我有一个微小的 Python 方法,根据我的性能分析器,它是远远的性能热点(超过95%的执行时间在此处),这是一个更大的程序中的一部分。
代码在Jython实现的Python中运行,而不是CPython,如果这很重要的话。seq是一个DNA序列字符串,大约有1,000个元素。logProbs是一个字典列表,每个位置一个字典。目标是找到任何长度为l(大约10-20个元素)的子序列的最大分数。我意识到所有这些循环都由于解释开销而低效,并且在静态编译/JIT'd语言中会快得多。但是,我不想切换语言。首先,我需要一个JVM语言来使用我的库,这限制了我的选择。其次,我不想将此代码整体翻译成较低级别的JVM语言。但是,如果必要的话,我愿意在其他地方重写此热点,尽管我不知道如何接口它或开销会是什么。除了这种方法的单线程缓慢性外,我还无法在并行化方面使程序扩展到4个CPU以上。鉴于它几乎在我发布的10行热点中花费了所有时间,我无法弄清楚这里的瓶颈在哪里。
def topScore(self, seq):
ret = -1e9999
logProbs = self.logProbs # save indirection
l = len(logProbs)
for i in xrange(len(seq) - l + 1):
score = 0.0
for j in xrange(l):
score += logProbs[j][seq[j + i]]
ret = max(ret, score)
return ret
代码在Jython实现的Python中运行,而不是CPython,如果这很重要的话。seq是一个DNA序列字符串,大约有1,000个元素。logProbs是一个字典列表,每个位置一个字典。目标是找到任何长度为l(大约10-20个元素)的子序列的最大分数。我意识到所有这些循环都由于解释开销而低效,并且在静态编译/JIT'd语言中会快得多。但是,我不想切换语言。首先,我需要一个JVM语言来使用我的库,这限制了我的选择。其次,我不想将此代码整体翻译成较低级别的JVM语言。但是,如果必要的话,我愿意在其他地方重写此热点,尽管我不知道如何接口它或开销会是什么。除了这种方法的单线程缓慢性外,我还无法在并行化方面使程序扩展到4个CPU以上。鉴于它几乎在我发布的10行热点中花费了所有时间,我无法弄清楚这里的瓶颈在哪里。
seq
和logProbs
的缩短样本? - KatriellogProbs
是一个字典列表..." - Fred LarsonlogProbs
列表中的每个项目都变成一个列表而不是一个字典。我相信seq[index]
可能只有很少的几个可能值。这将涉及到将每个可能的值逻辑映射到一个索引,但这可能比从序列哈希每个值以查找其是否为字典更快。 - martineau