如何计时Java程序执行速度
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2572868/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to time Java program execution speed
提问by George Mic
How do you time the execution of a java program? I'm not sure what class I should use to do this.
你如何计时 Java 程序的执行时间?我不确定我应该使用什么课程来做到这一点。
I'm kinda looking for something like:
我有点在寻找类似的东西:
// Some timer starts here
for (int i = 0; i < length; i++) {
// Do something
}
// End timer here
System.out.println("Total execution time: " + totalExecutionTime);
采纳答案by bua
final long startTime = System.currentTimeMillis();
for (int i = 0; i < length; i++) {
// Do something
}
final long endTime = System.currentTimeMillis();
System.out.println("Total execution time: " + (endTime - startTime));
回答by BalusC
You can make use of System#nanoTime()
. Get it before and after the execution and just do the math. It's preferred above System#currentTimeMillis()
because it has a better precision. Depending on the hardware and the platform used, you may otherwise get an incorrect gap in elapsed time. Here with Core2Duo on Windows, between about 0 and ~15ms actually nothing can be calculated.
您可以利用System#nanoTime()
. 在执行之前和之后获取它,然后进行数学计算。它在上面System#currentTimeMillis()
是首选,因为它具有更好的精度。根据所使用的硬件和平台,您可能会在经过的时间出现错误的间隔。在 Windows 上使用 Core2Duo,在大约 0 到 ~15 毫秒之间实际上无法计算任何内容。
A more advanced tool is a profiler.
一个更高级的工具是分析器。
回答by Jonathan Feinberg
You get the current system time, in milliseconds:
您获得当前系统时间,以毫秒为单位:
final long startTime = System.currentTimeMillis();
Then you do what you're going to do:
然后你做你要做的事情:
for (int i = 0; i < length; i++) {
// Do something
}
Then you see how long it took:
然后你会看到花了多长时间:
final long elapsedTimeMillis = System.currentTimeMillis() - startTime;
回答by Thomas
Have a look at System.currentTimeMillis()
.
回答by Jason
use long startTime=System.currentTimeMillis()
for start time, at the top of the loop
使用 longstartTime=System.currentTimeMillis()
作为开始时间,在循环的顶部
put long endTime= System.currentTimeMillis();
outside the end of the loop. You'll have to subtract the values to get the runtime in milliseconds.
放在long endTime= System.currentTimeMillis();
循环的末尾之外。您必须减去这些值才能获得以毫秒为单位的运行时间。
If you want time in nanoseconds, check out System.nanoTime()
如果您想要以纳秒为单位的时间,请查看 System.nanoTime()
回答by luis.espinal
public class someClass
{
public static void main(String[] args) // your app start point
{
long start = java.util.Calendar.getInstance().getTimeInMillis();
... your stuff ...
long end = java.util.Calendar.getInstance().getTimeInMillis();
System.out.println("it took this long to complete this stuff: " + (end - start) + "ms");
}
}
回答by rhu
Be aware that there are some issues where System#nanoTime()
cannot be reliably used on multi-core CPU's to record elapsed time ... each core has maintains its own TSC (Time Stamp Counter): this counter is used to obtain the nano time (really it is the number of ticks since the CPU booted).
请注意,有一些问题System#nanoTime()
无法在多核 CPU 上可靠地用于记录经过的时间……每个核都有自己的 TSC(时间戳计数器):此计数器用于获取纳米时间(实际上是自 CPU 启动以来的滴答数)。
Hence, unless the OS does some TSC time warping to keep the cores in sync, then if a thread gets scheduled on one core when the initial time reading is taken, then switched to a different core, the relative time can sporadically appear to jump backwards and forwards.
因此,除非操作系统进行一些 TSC 时间扭曲以保持内核同步,否则如果在读取初始时间时将线程安排在一个内核上,然后切换到不同的内核,则相对时间可能会偶尔出现倒退和转发。
I observed this some time ago on AMD/Solaris where elapsed times between two timing points were sometimes coming back as either negative values or unexpectedly large positive numbers. There was a Solaris kernel patch and a BIOS setting required to force the AMD PowerNow! off, which appeared to solved it.
我前段时间在 AMD/Solaris 上观察到了这一点,其中两个时间点之间的经过时间有时会以负值或意外大的正数的形式返回。需要一个 Solaris 内核补丁和一个 BIOS 设置来强制使用 AMD PowerNow!关闭,这似乎解决了它。
Also, there is (AFAIK) a so-far unfixed bug when using java System#nanoTime()
in a VirtualBox environment; causing all sorts of bizarre intermittent threading problems for us as much of the java.util.concurrency
package relies on nano time.
此外,System#nanoTime()
在 VirtualBox 环境中使用 java 时,有(AFAIK)一个迄今为止未修复的错误;给我们造成各种奇怪的间歇性线程问题,因为大部分java.util.concurrency
包都依赖于纳米时间。
See also:
也可以看看:
Is System.nanoTime() completely useless?http://vbox.innotek.de/pipermail/vbox-trac/2010-January/135631.html
System.nanoTime() 完全没用吗?http://vbox.innotek.de/pipermail/vbox-trac/2010-January/135631.html
回答by SyntaxT3rr0r
For simple stuff, System.currentTimeMillis()can work.
对于简单的东西,System.currentTimeMillis()可以工作。
It's actually so common that my IDE is setup so that upon entering "t0" it generates me the following line:
实际上,我的 IDE 设置如此普遍,因此在输入“t0”时,它会生成以下行:
final long t0 = System.currentTimeMillis()
But for more complicated things, you'll probably want to use statistical time measurements, like here (scroll down a bit and look at the time measurements expressed including standard deviations etc.):
但是对于更复杂的事情,您可能希望使用统计时间测量,如下所示(向下滚动并查看表示的时间测量,包括标准偏差等):
回答by dotrc
You may also try Perf4J. Its a neat way of doing what you are looking for, and helps in aggregated performance statistics like mean, minimum, maximum, standard deviation and transactions per second over a set time span. An extract from http://perf4j.codehaus.org/devguide.html:
您也可以尝试 Perf4J。它是做您正在寻找的事情的一种巧妙方式,并有助于汇总性能统计数据,例如在设定的时间跨度内的平均值、最小值、最大值、标准偏差和每秒事务数。摘自http://perf4j.codehaus.org/devguide.html:
StopWatch stopWatch = new LoggingStopWatch();
try {
// the code block being timed - this is just a dummy example
long sleepTime = (long)(Math.random() * 1000L);
Thread.sleep(sleepTime);
if (sleepTime > 500L) {
throw new Exception("Throwing exception");
}
stopWatch.stop("codeBlock2.success", "Sleep time was < 500 ms");
} catch (Exception e) {
stopWatch.stop("codeBlock2.failure", "Exception was: " + e);
}
Output:
输出:
INFO: start[1230493236109] time[447] tag[codeBlock2.success] message[Sleep time was < 500 ms]
INFO: start[1230493236719] time[567] tag[codeBlock2.failure] message[Exception was: java.lang.Exception: Throwing exception]
INFO: start[1230493237286] time[986] tag[codeBlock2.failure] message[Exception was: java.lang.Exception: Throwing exception]
INFO: start[1230493238273] time[194] tag[codeBlock2.success] message[Sleep time was < 500 ms]
INFO: start[1230493238467] time[463] tag[codeBlock2.success] message[Sleep time was < 500 ms]
INFO: start[1230493238930] time[310] tag[codeBlock2.success] message[Sleep time was < 500 ms]
INFO: start[1230493239241] time[610] tag[codeBlock2.failure] message[Exception was: java.lang.Exception: Throwing exception]
INFO: start[1230493239852] time[84] tag[codeBlock2.success] message[Sleep time was < 500 ms]
INFO: start[1230493239937] time[30] tag[codeBlock2.success] message[Sleep time was < 500 ms]
INFO: start[1230493239968] time[852] tag[codeBlock2.failure] message[Exception was: java.lang.Exception: Throwing exception]
回答by MarAja
Using System.currentTimeMillis() is the proper way of doing this. But, if you use command line, and you want to time the whole program approximately and quickly, think about:
使用 System.currentTimeMillis() 是正确的方法。但是,如果您使用命令行,并且想要大致快速地对整个程序计时,请考虑:
time java App
which allows you not to modify the code and time your App.
这允许您不修改代码和时间您的应用程序。