使用PyStone测试时为什么Jython表现不一致?

时间:2009-02-28 04:21:11

标签: java python performance jython benchmarking

我最近一直在和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如何在一个真正长期运行的过程中表现出来?

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

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

我正在使用Jython 2.5b1(主干:5903:5905,2009年1月9日,16:01:29),Java(TM)SE运行时环境(版本1.6.0_07-b06-153)和Java HotSpot(TM) MacOS X 10.5上的64位服务器VM(版本1.6.0_07-b06-57,混合模式)。

感谢您的回答。

5 个答案:

答案 0 :(得分:2)

这可能是jython 2.5b1中的一个错误。您应该考虑将其报告给jython团队。我刚刚在我的MacBook上使用当前稳定版本的jython(2.2.1)运行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结果或多或少相同。我重新进行了三次测试,并且一直得到非常相似的结果。

我也尝试给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尚未真正开始运行。较长运行的结果或多或少是有效的,并显示了hotspot / JIT的影响

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

答案 1 :(得分:2)

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

nathell@breeze:/usr/lib/python2.5/test$ python pystone.py 500000
Pystone(1.1) time for 500000 passes = 12.98
This machine benchmarks at 38520.8 pystones/second

nathell@breeze:/usr/lib/python2.5/test$ python pystone.py 1000000
Pystone(1.1) time for 1000000 passes = 26.05
This machine benchmarks at 38387.7 pystones/second

nathell@breeze:/usr/lib/python2.5/test$ ~/jython/jython pystone.py
Pystone(1.1) time for 50000 passes = 2.47788
This machine benchmarks at 20178.6 pystones/second

nathell@breeze:/usr/lib/python2.5/test$ ~/jython/jython pystone.py 500000
Pystone(1.1) time for 500000 passes = 19.7294
This machine benchmarks at 25342.9 pystones/second

nathell@breeze:/usr/lib/python2.5/test$ ~/jython/jython pystone.py 1000000
Pystone(1.1) time for 1000000 passes = 38.9272
This machine benchmarks at 25689 pystones/second

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

答案 2 :(得分: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发布性能将更加强调。你可以通过查看我运行的一些microbenchmarks(最初来自PyPy)来看到一些痛点。

答案 3 :(得分:1)

我很确定通过调整JVM配置可以改善结果(JRuby正在使用相当多的有趣标志来实现)并且我也非常确定可以调整垃圾收集。 如果您对此基准测试非常感兴趣,那么这是配置VM的良好资源:Tuning Garbage Collection。我还要看一下JRuby配置。

./亚历

答案 4 :(得分: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上进行基准测试,请添加评论