2

我最近一直在玩 Jython,并决定用 pystone 做一些快速而肮脏的基准测试。为了获得参考,我首先测试了 cPython 2.6,循环次数越来越多(我认为这可能是相关的,因为 Jython 应该在一段时间后才开始从 JIT 中获利)。

(richard garibaldi):/usr/local/src/pybench% python ~/tmp/pystone.py 
Pystone(1.1) time for 50000 passes = 1.04
This machine benchmarks at 48076.9 pystones/second

(richard garibaldi):/usr/local/src/pybench% python ~/tmp/pystone.py 500000 
Pystone(1.1) time for 500000 passes = 10.33
This machine benchmarks at 48402.7 pystones/second

(richard garibaldi):/usr/local/src/pybench% python ~/tmp/pystone.py 1000000 
Pystone(1.1) time for 1000000 passes = 19.6
This machine benchmarks at 51020.4 pystones/second

如您所见,cPython 的行为始终如一:完成测试所需的时间与循环次数成线性增加。知道了这一点,我开始测试 Jython。

(richard garibaldi):/usr/local/src/pybench% jython ~/tmp/pystone.py 
Pystone(1.1) time for 50000 passes = 2.29807
This machine benchmarks at 21757.4 pystones/second

(richard garibaldi):/usr/local/src/pybench% jython ~/tmp/pystone.py 500000 
Pystone(1.1) time for 500000 passes = 10.931
This machine benchmarks at 45741.4 pystones/second


(richard garibaldi):/usr/local/src/pybench% jython ~/tmp/pystone.py 1000000
Pystone(1.1) time for 1000000 passes = 107.183
This machine benchmarks at 9329.86 pystones/second

在第一次运行中,与它的 C 兄弟相比,Jython 运行得相当糟糕。当增加循环数时,它开始感觉更好,接近 cPython,就像我最初的假设所预测的那样。请注意,循环的数量增加了 10 倍,但 Jython 仅用了大约 5 倍的时间来完成它们。所以,正如你想象的那样,我期待 Jython 会在最终测试中真正发挥作用。然而,令我非常失望的是,它确实很糟糕:比最初的运行速度慢了两倍多。

您的假设是什么:为什么 Jython 的行为方式如此不一致?可能是 GC 在某个时刻开始了,并且花费了很多时间?我查看了 PyStone 的代码,垃圾收集似乎没有被关闭,但我希望 Java 的 GC 至少和 Python 的一样好......你认为这种减速是永久性的,还是会消失在增加循环次数后的某个时候?Jython 在真正长时间运行的进程中应如何表现?

编辑:不幸的是,java.lang.OutOfMemoryError如果我将循环数增加到 200 万,我会得到......

(当然,Jython 仍处于测试阶段,因此在最终版本中应该会变得更好。)

我正在使用 Jython 2.5b1 (trunk:5903:5905, Jan 9 2009, 16:01:29), Java(TM) SE Runtime Environment (build 1.6.0_07-b06-153) 和 Java HotSpot(TM) 64-Bit MacOS X 10.5 上的服务器 VM(内部版本 1.6.0_07-b06-57,混合模式)。

感谢您的回答。

4

5 回答 5

2

这可能是 jython 2.5b1 中的一个错误。您应该考虑将其报告给 jython 团队。我刚刚使用当前稳定版本的 jython (2.2.1) 在我的 MacBook 上运行了 pystone 基准测试,我得到了缓慢但一致的结果:

mo$ ~/Coding/Jython/jython2.2.1/jython pystone.py 50000
Pystone(1.1) time for 50000 passes = 2.365
This machine benchmarks at 21141.6 pystones/second

mo$ ~/Coding/Jython/jython2.2.1/jython pystone.py 500000
Pystone(1.1) time for 500000 passes = 22.246
This machine benchmarks at 22476 pystones/second

mo$ ~/Coding/Jython/jython2.2.1/jython pystone.py 1000000
Pystone(1.1) time for 1000000 passes = 43.94
This machine benchmarks at 22758.3 pystones/second

mo$ java -version
java version "1.5.0_16"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_16-b06-275)
Java HotSpot(TM) Client VM (build 1.5.0_16-132, mixed mode, sharing)

对我来说,cPython 结果或多或少是相同的。我重新进行了 3 次 eacht 测试,并且一直得到非常相似的结果。

我还尝试给 java 一个更大的初始和最大堆(-Xms256m -Xmx512m),但没有值得注意的结果

但是,将 JVM 设置为 -server(启动速度较慢,长时间运行性能更好,对“交互式”工作不太好)使情况有所改变:

mo$ ~/Coding/Jython/jython2.2.1/jython pystone.py 50000
Pystone(1.1) time for 50000 passes = 1.848
This machine benchmarks at 27056.3 pystones/second

mo$ ~/Coding/Jython/jython2.2.1/jython pystone.py 500000
Pystone(1.1) time for 500000 passes = 9.998
This machine benchmarks at 50010 pystones/second

mo$ ~/Coding/Jython/jython2.2.1/jython pystone.py 1000000
Pystone(1.1) time for 1000000 passes = 19.9
This machine benchmarks at 50251.3 pystones/second

我使用 (-server -Xms256m -Xmx512m) 进行了最后一次运行:

mo$ ~/Coding/Jython/jython2.2.1/jython pystone.py 5000000
Pystone(1.1) time for 5000000 passes = 108.664
This machine benchmarks at 46013.4 pystones/second

我的猜测是,第一次运行缓慢是由于 VM 启动/JIT 尚未真正启动。较长时间运行的结果或多或少是一致的,并显示了热点/JIT 的影响

也许你可以用更大的堆重新运行你的最后一个测试?要更改 JVM 开关,只需编辑 Jython 安装中的 jython 文件。

于 2009-02-28T11:42:32.470 回答
2

我的笔记本电脑运行 Ubuntu Jaunty 的结果与 JRE 1.6.0_12-b04 相同:

nathell@breeze:/usr/lib/python2.5/test$ python pystone.py 500000
Pystone(1.1) 500000 次传递的时间 = 12.98
这台机器的基准测试为 38520.8 pystones/秒

nathell@breeze:/usr/lib/python2.5/test$ python pystone.py 1000000
1000000 次传递的 Pystone(1.1) 时间 = 26.05
这台机器的基准测试为 38387.7 pystones/秒

nathell@breeze:/usr/lib/python2.5/test$ ~/jython/jython pystone.py
Pystone(1.1) 50000 次传递的时间 = 2.47788
这台机器的基准测试为 20178.6 pystones/秒

nathell@breeze:/usr/lib/python2.5/test$ ~/jython/jython pystone.py 500000
Pystone(1.1) 500000 次传递的时间 = 19.7294
这台机器的基准测试为 25342.9 pystones/秒

nathell@breeze:/usr/lib/python2.5/test$ ~/jython/jython pystone.py 1000000
Pystone(1.1) 1000000 次传递的时间 = 38.9272
这台机器的基准测试为 25689 pystones/秒

所以也许这毕竟与 JRE 而不是 Jython 版本有关。Armed Bear Common Lisp 项目在 JRE 1.6 的早期版本中遇到的问题也可能暗示了这一点。

于 2009-03-03T22:58:52.303 回答
2

对像 JVM 一样复杂的运行时环境进行基准测试是很困难的。即使不包括 JIT 和 GC,运行之间也会有很大的堆、内存布局和缓存变化。

对 Jython 有帮助的一件事是在单个 VM 会话中多次运行基准测试:一次用于预热 JIT,一次或多次单独测量。我做了很多 Jython 基准测试,不幸的是,通常需要 10-50 次尝试才能达到合理的时间

您可以使用一些 JVM 标志来观察 GC 和 JIT 行为,以了解预热期应该多长,但显然您不应该在打开调试标志的情况下进行基准测试。例如:

% ./jython -J-XX:+PrintCompilation -J-verbose:gc
  1       java.lang.String::hashCode (60 bytes)
  2       java.lang.String::charAt (33 bytes)
  3       java.lang.String::lastIndexOf (156 bytes)
  4       java.lang.String::indexOf (151 bytes)
[GC 1984K->286K(7616K), 0.0031513 secs]

如果您执行所有这些操作并使用 HotSpot Server VM,您会发现 Jython 在 pystone 上比 CPython 稍快,但这绝不代表 Jython 的总体性能。对于 2.5 版本,Jython 开发人员更加关注正确性而不是性能;在接下来的一年左右以 2.6/2.7/3.0 发布的性能将更加强调。通过查看我运行的一些微基准(最初源自 PyPy),您可以看到一些痛点。

于 2009-04-03T14:41:15.980 回答
1

我很确定可以通过调整 JVM 配置来改进结果(JRuby 使用了很多有趣的标志来做到这一点),而且我也很确定可以调整垃圾收集。如果您对这个基准非常感兴趣,这里有一个很好的配置 VM 的资源:Tuning Garbage Collection。我还要看看 JRuby 配置。

./亚历克斯

于 2009-02-28T04:54:15.540 回答
1

我在 XP_Win32_PC 上的长凳:

C:\jython\jython2.5b1>bench "50000"

C:\jython\jython2.5b1>jython Lib\test\pystone.py "50000"
Pystone(1.1) time for 50000 passes = 1.73489
This machine benchmarks at 28820.2 pystones/second

C:\jython\jython2.5b1>bench "100000"

C:\jython\jython2.5b1>jython Lib\test\pystone.py "100000"
Pystone(1.1) time for 100000 passes = 3.36223
This machine benchmarks at 29742.2 pystones/second

C:\jython\jython2.5b1>bench "500000"

C:\jython\jython2.5b1>jython Lib\test\pystone.py "500000"
Pystone(1.1) time for 500000 passes = 15.8116
This machine benchmarks at 31622.3 pystones/second

C:\jython\jython2.5b1>bench "1000000"

C:\jython\jython2.5b1>jython Lib\test\pystone.py "1000000"
Pystone(1.1) time for 1000000 passes = 30.9763
This machine benchmarks at 32282.8 pystones/second

C:\jython\jython2.5b1>jython
Jython 2.5b1 (trunk:5903:5905, Jan 9 2009, 16:01:29)
[Java HotSpot(TM) Client VM (Sun Microsystems Inc.)] on java1.5.0_17

它不是那么快,但是......

没有“特效”

是 java-vm 的“问题”吗?

如果您想了解我在这台旧 Win32-PC 上的基准测试的更多信息,请添加评论

于 2009-03-02T14:44:58.787 回答