У меня есть следующий крошечный метод 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
Код выполняется в Jython реализация Python, а не CPython, если это важно. seq
представляет собой строку последовательности ДНК порядка 1000 элементов. logProbs
- это список словарей, по одному для каждой позиции. Цель состоит в том, чтобы найти максимальную оценку любой длины l
(порядка 10-20 элементов) подпоследовательности seq
.
Я понимаю, что весь этот цикл неэффективен из-за накладные расходы на интерпретацию и были бы намного быстрее на статически скомпилированном / JIT-языке. Однако я не хочу переключать языки. Во-первых, мне нужен язык JVM для библиотек, которые я использую, и это ограничивает мой выбор. Во-вторых, я не хочу полностью переводить этот код на язык JVM более низкого уровня. Тем не менее, я готов переписать эту точку доступа во что-нибудь еще, если это необходимо, хотя я не знаю, как с ней взаимодействовать и какие будут накладные расходы.
Помимо однопоточной медленности этого метода, я также могу Я не могу заставить программу масштабироваться намного больше, чем 4 CPU с точки зрения распараллеливания. Учитывая, что он проводит почти все свое время в 10-строчной точке доступа, которую я опубликовал, я не могу понять, в чем может быть узкое место.