Есть ли эквивалент Python для разыменования в Perl?

В настоящее время я переношу базу кода, первоначально реализованную в Perl, на Python. Следующий короткий фрагмент кода занимает около 90% значительного времени выполнения, когда я запускаю весь набор данных.

def equate(): for i in range(row): for j in range(row): if adj_matrix[i][j] != adj_matrix[mapping[i]][mapping[j]]: return False return True 

Если equate является замыканием внутри другого метода, строка является целым числом, adj_matrix – это список списков, представляющих матрицу, а отображение – список, представляющий вектор.

Эквивалентный код Perl выглядит следующим образом:

 sub equate { for ( 0..$row) { my ($smrow, $omrow) = ($$adj_matrix[$_], $$adj_matrix[$$mapping[$_]]); #DEREF LINE for (0..$row) { return 0 if $$smrow[$_] != $$omrow[$$mapping[$_]]; } } return 1; } 

Это инкапсулируется как sub ref во внешнюю подпрограмму, поэтому мне не нужно передавать переменные в подпрограмму.

Короче говоря, версия Perl намного быстрее, и мое тестирование показывает, что это связано с разыменованием в «DEREF LINE». Я пробовал то, что, как я полагал, был эквивалентным в Python:

  def equate(): for i in range(row): row1 = adj_matrix[i] row2 = adj_matrix[mapping[i]] for j in range(row): if row1[j] != row2[mapping[j]]: return False return True 

Но это было незначительное улучшение. Кроме того, я попытался использовать матрицу NumPy для представления adj_matrix, но опять же это небольшое улучшение, вероятно, потому, что adj_matrix, как правило, представляет собой небольшую матрицу, поэтому накладные расходы NumPy намного больше, и я не выполняю никаких математических операций с матрицей.

Я приветствую любое предложение по улучшению времени выполнения метода equate Python и объяснение, почему мой «улучшенный» метод equate Python не намного лучше. Хотя я считаю себя компетентным программистом на Perl, я начинаю Python.


ДОПОЛНИТЕЛЬНЫЕ ДЕТАЛИ:

Я использую Python 3.4, хотя подобное поведение наблюдалось, когда я первоначально реализовал его в версии 2.7. Я переключился на 3.4, так как лаборатория, в которой я работаю, использует 3.4.

Что касается содержимого векторов, позвольте мне предоставить некоторый фон, поэтому следующие данные имеют смысл. Это является частью алгоритма идентификации изоморфизмов подграфа между двумя химическими соединениями (a и b), представленными графиками A и B соответственно, где каждый атом является узлом и каждая связывает ребро. Вышеприведенный код предназначен для упрощенного случая, когда A = B, поэтому я ищу симметричные преобразования соединения (плоскости симметрии), а размер A в количестве атомов равен N. Каждому атому присваивается уникальный индекс, начинающийся с нуль.

Отображение является 1D-вектором размерностей 1xN, где каждый элемент в отображении является целым числом. mapping[i] = j представляет, что атом с индексом i (будет обозначаться как атом i или общий атомный индекс) в настоящее время отображается на атом j. Отсутствие отображения обозначается j = -1.

Adj_matrix – двумерная матрица размеров NxN, где каждый элемент adj_matrix [i] [j] = k является натуральным числом и представляет собой наличие и порядок ребра между атомами i и j в соединении A. Если k = 0, то нет такое ребро (AKA нет связи между i и j) иначе k> 0 и k представляет собой порядок связи между атомами i и j.

Когда A! = B, существуют два разных adj_matrices, которые сравниваются в equate, а размер a и b в атомах – Na и Nb. Na не должно равняться Nb, но Na = <Nb. Я упоминаю только об этом, так как оптимизация возможна для особого случая, который недействителен в общем случае, но любые советы были бы полезными.

One Solution collect form web for “Есть ли эквивалент Python для разыменования в Perl?”

С numpy вы можете векторизовать весь свой код следующим образом, предполагая, что adj_matrix и mapping являются массивами numpy:

 def equate(): row1 = adj_matrix[:row] row2 = adj_matrix[mapping[:row]] return np.all(row1 == row2) 

Он не разрывается на раннем этапе цикла, если обнаруживает несоответствие, но если ваши массивы не огромны, скорость NumPy будет доминировать.

  • Зачем использовать Parrot (или другую VM), если у меня есть переводчик?
  • Как использовать выражение Perl s // в выражении?
  • Программирование самообучающегося музыкального мастера
  • Как обрабатывать utf8 в командной строке (используя Perl или Python)?
  • разница между хешем perl и словарем python
  • Perl эквивалент интерпретаций списка Python со встроенным if-выражением?
  • Почему моя версия Python медленнее, чем моя версия Perl?
  • Эффективно усреднять второй столбец по интервалам, определенным первым столбцом
  • Python - лучший язык программирования в мире.