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