gpt4 book ai didi

java - 从 Jython 调用重载的 Java 方法

转载 作者:搜寻专家 更新时间:2023-10-31 20:22:38 24 4
gpt4 key购买 nike

当我从 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 中的第一个方法,脚本几乎不需要任何时间。我很困惑为什么方法重载时需要这么长时间。我在这里遗漏了什么吗?

最佳答案

你的代码!!

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字节数,即大约 500000000 字节477 兆字节其中 32 是 Java 中 float 的大小。
  3. 当您说 TestClass.overloaded([z,z,z]) 时,您总是会调用 4 维重载方法!!如果您不相信我,请尝试一下!

我的代码工作正常!!

我刚刚将 TestClass.overloaded([z,z,z]) 更改为 x = TestClass.overloaded([z,z,z])。而且执行速度非常快。但是打印 'x' 它仍然失败!! 为什么?!

“为什么”部分!!

失败是因为当你执行 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

输出:

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 字节!拿我用过的代码,然后把所有的2改成20

但是为什么不取消第一个方法的注释会花费时间!!!

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

玩得开心!!

关于java - 从 Jython 调用重载的 Java 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9440438/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com