从Jython调用重载Java方法的数组
当我从Jython脚本调用重载的Java方法时,我看到了一些奇怪的行为,我不明白
下面是我的Java类:
public class TestClass {
public static float[][][] overloaded(float[][][] x) {
return x;
}
public static float[][][][] overloaded(float[][][][] x) {
return x;
}
public static float[][][] zeros(int n1, int n2, int n3) {
return new float[n3][n2][n1];
}
}
这是我的Jython脚本:
import time,TestClass
n1,n2,n3 = 250,250,250
z = TestClass.zeros(n1,n2,n3)
start = time.time()
TestClass.overloaded([z,z,z])
print 'time =',(time.time()-start)
这个Jython脚本运行大约需要1分钟,但是如果我注释掉TestClass中的第一个方法,那么脚本几乎不需要任何时间。我很困惑,当方法重载时,为什么要花这么长的时间。我错过什么了吗
# 1 楼答案
你的代码
事实
n1,n2,n3 = 250,250,250
并说z = TestClass.zeros(n1,n2,n3)
时,基本上你是在分配250x250x250x32 bytes
,即500000000 bytes
或477 megabytes
其中32
是Java中浮点的大小李>TestClass.overloaded([z,z,z])
时,你总是要调用四维重载方法!!如果你不相信我,试试看李>我的代码运行良好
我刚把
TestClass.overloaded([z,z,z])
改成了x = TestClass.overloaded([z,z,z])
。而且执行速度非常快。但是在印刷时,为什么“为什么”部分
它之所以失败,是因为当您执行
TestClass.overloaded([z,z,z])
或当我打印'x'
时,python或jython需要以字符串表示形式转换对象,这就是问题所在。请参见下面的stacktrace:看。。JVM被炸了!!!!堆空间不足。。。即使你改变了JVM的内存参数,并用更多的内存来祝福这个程序,即使你所说的
478 MB !!
(这不仅仅是478 MB
,因为你传递的是一个'z'
数组,每个数组都是478 MB
!!!)这就是您分配的而已,而且JVM将需要内存来保存StringBuilder
字符串表示和其他一些东西相信我,这需要时间和大量的时间
只是给你一些感觉
^{
看看字符串的大小,它只是数组的
2x2x2x32 bytes
!!以我使用的代码为例,然后用20's
更改所有的2's
但是为什么不取消第一个方法的注释会花时间呢
请记住,为了解决纠正重载函数的问题,jython需要计算
[z,z,z]
,这是一个很好的内存量。这就是你看到的延迟。当您注释第一个方法时,就不会对调用产生混淆,因此它会立即返回。如果我使用你的代码,那么首先需要解析上述表达式,然后计算对象的字符串表示形式。综合起来,需要很长时间才能再次做出反应。但是,如果我使用您的代码的修改版本,即x = TestClass.overloaded([z,z,z])
,那么它会变得更快,但仍然需要时间打印'x'
,或者可能会导致Heap Exception
玩得开心