繁体   English   中英

是否有一个Python相当于在Perl中解除引用?

[英]Is there a Python equivalent to dereferencing in 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;
 }

这被封装为外部子例程中的子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的开销要大得多,而且我并没有真正做任何矩阵数学运算。

我欢迎任何改进Python equate方法的运行时的建议,并解释为什么我的“改进的”Python 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的2D矩阵,其中每个元素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的速度将占主导地位。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM