为什么在 Maven Surefire 中指定 Xss 会使 ScalaTest 运行 快两倍?
Why does specifying Xss in Maven Surefire make ScalaTest run twice as fast?
我有一个 FunSuite 单元测试来测试一个高度递归(非尾部)的 Scala 函数。如果我将下面的行添加到我的 pom.xml Surefire <configuration>
它运行速度是原来的两倍。
<argLine>-Xss1024k</argLine>
我指定什么值并不重要,除非我指定一个非常低的值,如 -Xss256k,我会得到预期的 WhosebugException。否则,我可以将它设置为 512k 到 512m 之间的任何位置,并且执行时间都是一样的。但是,如果我从 pom.xml 中完全删除该行,则执行时间会加倍。
为什么会这样?
JVM 规范指出,
Because the Java Virtual Machine stack is never manipulated directly
except to push and pop frames, frames may be heap allocated. The
memory for a Java Virtual Machine stack does not need to be
contiguous.
This specification permits Java Virtual Machine stacks either to be of
a fixed size or to dynamically expand and contract as required by the
computation. If the Java Virtual Machine stacks are of a fixed size,
the size of each Java Virtual Machine stack may be chosen
independently when that stack is created.
我认为您使用的jvm 支持动态扩展堆栈。当调用链大于默认的初始堆栈大小时,将从堆中分配堆栈帧。这会导致执行变慢。
如果您使用参数指定堆栈大小,堆栈可能会在固定大小模式下工作。在这种情况下,所有 space 都将事先分配,并且不需要新的分配。此外,当您提供低堆栈大小时,它不会扩展并抛出 Whosebug,这也表明它正在固定大小模式下工作。
由于您没有提到您正在使用的 JVM 实现,这只是我根据 JVM 规范和您的用例中的信息做出的假设。
https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.5.2
我有一个 FunSuite 单元测试来测试一个高度递归(非尾部)的 Scala 函数。如果我将下面的行添加到我的 pom.xml Surefire <configuration>
它运行速度是原来的两倍。
<argLine>-Xss1024k</argLine>
我指定什么值并不重要,除非我指定一个非常低的值,如 -Xss256k,我会得到预期的 WhosebugException。否则,我可以将它设置为 512k 到 512m 之间的任何位置,并且执行时间都是一样的。但是,如果我从 pom.xml 中完全删除该行,则执行时间会加倍。
为什么会这样?
JVM 规范指出,
Because the Java Virtual Machine stack is never manipulated directly except to push and pop frames, frames may be heap allocated. The memory for a Java Virtual Machine stack does not need to be contiguous.
This specification permits Java Virtual Machine stacks either to be of a fixed size or to dynamically expand and contract as required by the computation. If the Java Virtual Machine stacks are of a fixed size, the size of each Java Virtual Machine stack may be chosen independently when that stack is created.
我认为您使用的jvm 支持动态扩展堆栈。当调用链大于默认的初始堆栈大小时,将从堆中分配堆栈帧。这会导致执行变慢。
如果您使用参数指定堆栈大小,堆栈可能会在固定大小模式下工作。在这种情况下,所有 space 都将事先分配,并且不需要新的分配。此外,当您提供低堆栈大小时,它不会扩展并抛出 Whosebug,这也表明它正在固定大小模式下工作。
由于您没有提到您正在使用的 JVM 实现,这只是我根据 JVM 规范和您的用例中的信息做出的假设。
https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.5.2