从Jython调用重载的Java方法

use*_*973 5 java arrays jython multidimensional-array

当我从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];
  }
}
Run Code Online (Sandbox Code Playgroud)

这是我的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)
Run Code Online (Sandbox Code Playgroud)

这个Jython脚本大约需要1分钟才能运行,但如果我在TestClass中注释掉第一个方法,那么脚本几乎不需要任何时间.我很困惑为什么在方法重载时需要这么长时间.我在这里错过了什么吗?

Fav*_*ius 3

你的代码!

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)
Run Code Online (Sandbox Code Playgroud)

事实!!

  1. Jython 基于 Java(我们已经知道了!!)
  2. 当你这样做n1,n2,n3 = 250,250,250和说z = TestClass.zeros(n1,n2,n3)时,本质上你是在或250x250x250x32 bytes周围分配。Java中float的大小在哪里?500000000 bytes477 megabytes 32
  3. 当你说TestClass.overloaded([z,z,z])then 时,你总是会调用 4 维重载方法!不信就试试吧!!

我的代码工作正常!

我刚刚将其更改TestClass.overloaded([z,z,z])x = TestClass.overloaded([z,z,z]). 而且执行速度非常快。但在打印“x” it still fails!!时为什么?!

“为什么”部分!

它会失败,因为当你这样做TestClass.overloaded([z,z,z])或当我打印时,'x'因为 python 或者 jython 需要将对象转换为字符串表示形式,这就是问题所在。请参阅下面的堆栈跟踪:

java.lang.OutOfMemoryError: Java heap space
        at java.util.Arrays.copyOfRange(Arrays.java:3209)
        at java.lang.String.<init>(String.java:215)
        at java.lang.StringBuilder.toString(StringBuilder.java:430)
        at org.python.core.PyList.list_toString(PyList.java:472)
        at org.python.core.PyList.toString(PyList.java:450)
        at org.python.core.PyArray.toString(PyArray.java:395)
        at org.python.core.PyObject.__repr__(PyObject.java:174)
        at org.python.core.PyList.list_toString(PyList.java:464)
        at org.python.core.PyList.toString(PyList.java:450)
        at org.python.core.PyArray.toString(PyArray.java:395)
        at org.python.core.PyObject.__repr__(PyObject.java:174)
Run Code Online (Sandbox Code Playgroud)

看.. JVM 被轰炸了!!!!它超出了堆空间...即使您更改了内存的 JVM 参数并为该程序提供了更多的祝福,即使您正在谈论(好吧,这不仅仅是因为您正在传递一个数组,并且每个数组都是!! !)这正是所分配的,除此之外,JVM 还需要内存来保存字符串表示形式和其他一些东西! 478 MB !! 478 MB'z'478 MBStringBuilder

相信我,这需要时间,而且是大量的时间。

只是为了给大家一些感受!!

>>> n1,n2,n3 = 2,2,2
>>> z = TestClass.zeros(n1,n2,n3)
>>> x = TestClass.overloaded([z,z,z])
>>> x
Run Code Online (Sandbox Code Playgroud)

Output:

array([[[F, [array([[F, [array([F, [array('f', [0.0, 0.0]), array('f', [0.0, 0.0
])]), array([F, [array('f', [0.0, 0.0]), array('f', [0.0, 0.0])])]), array([[F,
[array([F, [array('f', [0.0, 0.0]), array('f', [0.0, 0.0])]), array([F, [array('
f', [0.0, 0.0]), array('f', [0.0, 0.0])])]), array([[F, [array([F, [array('f', [
0.0, 0.0]), array('f', [0.0, 0.0])]), array([F, [array('f', [0.0, 0.0]), array('
f', [0.0, 0.0])])])])
Run Code Online (Sandbox Code Playgroud)

查看字符串的大小,它只是2x2x2x32 bytes数组的大小!拿我用过的代码,然后2's20's.

但是,当您不取消第一个方法的注释时,为什么要花时间!

请记住,为了解决正确的重载函数,jython 需要评估哪个[z,z,z]内存量合适。这就是你看到延迟的地方。当您注释第一个方法时,调用就不会混淆,因此它会立即返回。如果我使用您的代码,那么首先需要解析上述表达式,然后计算对象的字符串表示形式。综合起来,需要很长时间才能再次做出反应。但是,如果我使用您的代码的修改版本,x = TestClass.overloaded([z,z,z])即它会变得更快一点,但打印仍然需要时间'x',或者可能会导致Heap Exception

玩得开心 !!