Python 确定包含特定项的矩阵行子集的快速方法

Python 确定包含特定项的矩阵行子集的快速方法,python,list,algorithm,performance,optimization,Python,List,Algorithm,Performance,Optimization,我正在寻找一个解决以下问题的时间效率高的解决方案,它利用了我想多次执行某个操作的事实。我在下面实现了两种方法,我发现其中一种速度要快得多。我想知道这两种方法是否有更有效的替代方法 Input:维度为m*n的矩阵矩阵矩阵填充了非负整数(0TL;DR:是的,有一种更好的方法可以使用numpy进行计算。但是,请注意,存在一种2D随机内存间接模式,通常速度较慢,并且很难优化 有用信息: 随机内存访问速度很慢。事实上,处理器很难预测要获取的内存地址,从而减少内存的延迟。只要数据适合缓存并重复使用多次,这并

我正在寻找一个解决以下问题的时间效率高的解决方案,它利用了我想多次执行某个操作的事实。我在下面实现了两种方法,我发现其中一种速度要快得多。我想知道这两种方法是否有更有效的替代方法


Input:维度为m*n的矩阵矩阵矩阵填充了非负整数(0TL;DR:是的,有一种更好的方法可以使用numpy进行计算。但是,请注意,存在一种2D随机内存间接模式,通常速度较慢,并且很难优化

有用信息: 随机内存访问速度很慢。事实上,处理器很难预测要获取的内存地址,从而减少内存的延迟。只要数据适合缓存并重复使用多次,这并不太糟糕。在巨大内存区域上进行的随机内存访问速度要慢得多,应该像瘟疫一样避免(如果可能的话)

分析: 这两种方法在执行表达式
isPresent[qs[j][i]
isPresent[i][qs[j]]
时都会执行随机内存间接寻址。 这种间接寻址速度很慢,但方法2的速度较慢,因为提取地址之间的平均距离往往比方法1大得多,从而产生一种称为缓存抖动的效果

更快的解决方案:Numpy可用于显著提高第一种方法的性能(得益于“矢量化”本机方法)。 实际上,这种方法使用普通的python循环,这些循环通常非常慢,并且多次重新计算
isPresent[qs[j]]
。 以下是更快的实现:

# Assume vecs is a list of np.arrray rather than a list of list

isPresent = [numpy.array([False]*m) for i in range(b+1)]
for i in range(m):
    for j in mat[i]:
        isPresent[j][i] = True

time3 = 0.0
for j in range(p):
    st3 = time.time()
    tmp = isPresent[qs[j]]
    result3 = numpy.extract(tmp[vecs[j]], vecs[j])
    time3 += time.time() - st3
绩效结果:

time1:  0.165357
time2:  0.309095
time3:  0.007201
新版本比第一种方法快23倍,比第二种方法快43倍


请注意,通过并行计算
j
-循环可以大大加快这一速度,但这有点复杂。

我怀疑这是一个缓存问题。您的方法1似乎具有更好的访问局部性。我不知道在Python中将
isPresent
标记打包为每个标记1位有多实际?是or吗
result
中元素的顺序是否重要?如果是,这是部分顺序还是全部顺序?谢谢。今天早些时候我定义了一个类似的变量“tmp”,它导致了显著的速度提高。在我的应用程序中,似乎在解决方案中使用numpy数组会使速度显著降低(4倍)。
time1:  0.165357
time2:  0.309095
time3:  0.007201