我在IronPython中根据代码here进行了以下矩阵乘法基准测试:
from System import Random
from System.Diagnostics import Stopwatch
def zero(m,n):
# Create zero matrix
new_matrix = [[0 for row in range(n)] for col in range(m)]
return new_matrix
def rand(m,n):
# Create random matrix
rnd = Random(1)
new_matrix = [[rnd.NextDouble() for row in range(n)] for col in range(m)]
return new_matrix
def show(matrix):
# Print out matrix
for col in matrix:
print col
def mult(matrix1,matrix2):
# Matrix multiplication
if len(matrix1[0]) != len(matrix2):
# Check matrix dimensions
print 'Matrices must be m*n and n*p to multiply!'
else:
# Multiply if correct dimensions
watch = Stopwatch()
print 'mult1 start....'
watch.Start()
new_matrix = zero(len(matrix1),len(matrix2[0]))
for i in range(len(matrix1)):
for j in range(len(matrix2[0])):
for k in range(len(matrix2)):
new_matrix[i][j] += matrix1[i][k]*matrix2[k][j]
watch.Stop()
print 'mult1 end.'
print watch.ElapsedMilliseconds
return new_matrix
from System import Array
def ListToArray(matrix):
n = len(matrix)
m = len(matrix[0])
a = Array.CreateInstance(float, n, m)
for i in range(n):
for j in range(m):
a[i,j] = matrix[i][j]
return a
def mult2(matrix1, matrix2):
N = len(matrix1)
K = len(matrix2)
M = len(matrix2[0])
m1 = ListToArray(matrix1)
m2 = ListToArray(matrix2)
res = ListToArray(rand(len(matrix1), len(matrix2[0])))
watch = Stopwatch()
print 'mult2 start...'
watch.Start()
for i in range(N):
for j in range(M):
for k in range(K):
res[i,j] += m1[i,k]*m2[k,j]
watch.Stop()
print 'mult2 ends.'
print watch.ElapsedMilliseconds
return res
if __name__ == '__main__':
#a = rand(280,10304)
#b = rand(10304,280)
a = rand(280,10)
b = rand(10,280)
c = mult2(a, b)
d = mult(a, b)
我想尝试两个大矩阵(280乘10304和10304乘208),但两个版本都不能在短时间内产生结果。
然后我尝试了一个小得多的(如代码中所示),结果如下:
mult2 : 7902 ms
mult1 : 420 ms
表示在IronPython中使用.NET数组比python List慢得多。
另请注意,C#对两个大矩阵使用约12秒。 IronPython已经在10K倍的小盒子上花了很多钱。我不确定我的计算机中的IronPython设置是否错误,如果没有,IronPython对于数字代码来说真的很慢。
答案 0 :(得分:2)
对于您的特定问题,我认为问题是boxing - 在IronPython中,列表项(以及所有其他变量)都存储在框中,因此仅对框内值进行操作。但是,CLR数组元素没有装箱,因此IronPython必须在从数组中提取它们时将它们装箱,然后在返回的路上取消装箱.C#可以对未装箱的值进行操作,并进行一系列其他优化使IronPython没有快速制作数组。
如果你想快速数学数学,NumPy for IronPython可能是更好的选择。
答案 1 :(得分:1)
在我们的项目中,我们试图避免使用.Net类,直到这变得非常必要。我想没有任何特别需要使用Array进行矩阵乘法,因为python为您提供了几种处理矩阵,集合或numpy等矩阵的方法。
答案 2 :(得分:0)
使用高级语言处理矩阵时,您可能会以某种方式降低速度。如果你想在.net中这样做,试试http://numerics.mathdotnet.com/ - 他们已经完成了改善矩阵运算的可能性。
这并不能解释为什么你会看到差异,但如果你正在寻找一些快速解决方案,可能会有所帮助。
答案 3 :(得分:0)
我的猜测是,与普通的Python列表相比,杀死性能的是多维数组的使用。我可以很容易地看到这是一条缓慢的路径,如果你自己切换到阵列数组或计算索引,你可以看到一个大的加速。
其他人指出,这不是像Python这样的动态语言的最佳代码。但IronPython的一大好处就是可以轻松无缝地引入C#片段来加速这样的案例。