是否有一个Python等价于在Perl中解引用?

我目前正在将一个代码库移植到Python中,我最初是用Perl实现的。 当我在整个数据集上运行时,以下一小段代码占用了大约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是另一种方法中的闭包,row是整数,adj_matrix是表示矩阵的列表列表,mapping是表示矢量的列表。

等效的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;
 }

这被封装在子外部子程序中,因此我不必将变量传递给子程序。

简而言之,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的开销要大得多,而且我没有真正进行任何矩阵数学运算。

我欢迎任何有关改进Python equate方法的运行时间的建议,以及为什么我的“改进”Python equate方法没有equate的解释。 虽然我认为自己是一名称职的Perl程序员,但我是一名Python新手。


额外细节:

我使用的是Python 3.4,尽管当我在2.7中最初实现它时观察到了类似的行为。 自从我工作的实验室使用3.4以来,我改用了3.4。

至于矢量的内容,请允许我提供一些背景,以便以下细节有意义。 这是识别由图A和B分别表示的两种化合物(a和b)之间的子图同构的算法的一部分,其中每个原子是节点并且每个原子都是边缘。 上面的代码适用于A = B的简化情况,所以我正在寻找化合物的对称变换(对称平面),并且原子数量中的A的大小为N.每个原子被分配一个唯一的索引,从零。

映射是维度为1xN的一维向量,其中映射中的每个元素都是整数。 mapping[i] = j ,表示具有索引i的原子(将被称为原子i或一般原子'索引')当前被映射到原子j。 映射的缺失由j = -1表示。

Adj_matrix是尺寸为NxN的二维矩阵,其中每个元素adj_matrix [i] [j] = k是一个自然数并且表示化合物A中原子i和j之间边缘的存在和顺序。如果k = 0,则不存在这种边缘(AKA在i和j之间没有键),否则k> 0,并且k表示原子i和j之间的键的顺序。

当A!= B时,有两个不同的adj_matrices被equate比较,并且原子中的a和b的大小是Na和Nb。 Na不必等于Nb,但Na = <Nb。 我只提到这一点,因为对于在一般情况下无效的特例,优化是可能的,但任何建议都会有帮助。


使用numpy可以将整个代码按如下方式进行矢量化,假设adj_matrixmapping是numpy数组:

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

如果发现不匹配,它不会在循环的早期发现,但除非您的阵列很大,否则NumPy的速度将占主导地位。

链接地址: http://www.djcxy.com/p/24089.html

上一篇: Is there a Python equivalent to dereferencing in Perl?

下一篇: Ruby vs Java: Why world is going to end faster with Java?