【发布时间】:2010-11-17 22:24:03
【问题描述】:
我有以下小型 Python 方法,它是到目前为止的性能热点(根据我的分析器,>95% 的执行时间都花在了这里)一个更大的程序:
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
代码在 Python 的 Jython 实现中运行,而不是在 CPython 中运行,如果这很重要的话。 seq 是一个 DNA 序列字符串,大约有 1,000 个元素。 logProbs 是一个字典列表,每个位置一个。目标是找到seq的任意长度l(大约10-20个元素)子序列的最高分。
我意识到所有这些循环由于解释开销而效率低下,并且在静态编译/JIT 语言中会快得多。但是,我不愿意切换语言。首先,我需要为我正在使用的库提供一种 JVM 语言,这限制了我的选择。其次,我不想将这段代码批量翻译成较低级别的 JVM 语言。但是,如果有必要,我愿意用其他东西重写这个热点,尽管我不知道如何接口它或开销是多少。
除了这种方法的单线程缓慢之外,我也无法让程序在并行化方面扩展到超过 4 个 CPU。鉴于它几乎将所有时间都花在了我发布的 10 行热点中,我无法弄清楚这里的瓶颈可能是什么。
【问题讨论】:
-
我无法完全理解您正在使用的数据结构。你能发布一个简短的
seq和logProbs示例吗? -
我的第一个想法是 numpy,所以也许这个页面上的一些东西可能有用:stackoverflow.com/questions/316410/…
-
我的第二个想法是改变迭代,这样你只检查 seq 一次,但这可能意味着 logProbs 和 score 变得更加复杂,并且实际上可能不会减少完成的工作。
-
@Russell:Jython 中没有 numpy,但我认为您应该能够访问 Java 的数字。
-
@Fred Larson:抱歉,我的意思是让
logProbs列表中的每个项目都成为列表而不是字典。我相信seq[index]可以拥有的可能值很少。这需要在逻辑上将每个可能的值映射到索引,但这可能比从序列中散列每个值以查找其值(如果它是字典)更快。
标签: java python performance jvm jython