从Jython调用重载的Java方法

时间:2012-02-25 01:53:05

标签: java arrays multidimensional-array jython

当我从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 个答案:

答案 0 :(得分: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)

事实!!

  1. Jython是基于Java的(我们已经知道!!)
  2. 当您执行n1,n2,n3 = 250,250,250并说z = TestClass.zeros(n1,n2,n3)时,基本上您正在分配250x250x250x32 bytes500000000 bytes周围的477 megabytes 32 是Java中浮点数的大小。
  3. 当你说TestClass.overloaded([z,z,z])时,你总是会打电话给4维重载方法!!如果你不相信我,试试吧!!
  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)
    

    请参阅.. JVM遭到轰炸!!!!它的堆空间了......即使你改变了JVM参数的内存和更多的祝福这个程序,即使这样你谈论的 478 MB !! (当然它不只是478 MB,因为要传递的阵列'z',并将它们中的每一个是478 MB !!!) 那是只是你分配的内容,除了JVM需要内存StringBuilder来保存字符串表示和其他一些东西!

    相信我需要时间和时间。

    只是为了给你一些感觉!!

    >>> n1,n2,n3 = 2,2,2
    >>> z = TestClass.zeros(n1,n2,n3)
    >>> x = TestClass.overloaded([z,z,z])
    >>> x
    

    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])])])])
    

    查看字符串的大小,它只适用于数组的2x2x2x32 bytes!获取我使用的代码,然后使用2's更改所有20's

    但是为什么在没有取消注释第一种方法时需要时间!!!

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

    玩得开心!!