Asa*_*iev 21 java execution-time
正如我在启动Java应用程序之前所知道的那样,它为它分配了一些RAM,并且这个内存可以在启动之前由用户控制.但是当我启动应用程序时,每次都有不同的执行时间,还有另一个问题.
这是一个非常简单的for循环示例:
package timespent;
public class Main {
public static void main(String[] args) {
long startTime = System.nanoTime();
int j = 0;
for (int i = 0; i < 1.E6; i++) {
j = i + 1;
}
long endTime = System.nanoTime();
long duration = (endTime - startTime);
System.out.println("duration = " + duration);
}
}
Run Code Online (Sandbox Code Playgroud)
它打印出不同的结果:
duration = 5720542
duration = 7331307
duration = 7737946
duration = 6899173
Run Code Online (Sandbox Code Playgroud)
假设我希望它能够精确地执行10,000,000纳秒或10毫秒.
我希望java应用程序执行精确的时间执行.
当我启动一个应用程序时,我想在加载所有组件之前显示应用程序启动窗口上剩下的确切执行时间.
我想这是一种CPU操作,我想知道它是否可能.
Q1:在Java中有可能吗?
Q2:如果在Java中不可能,那么有没有办法通过访问OS本机方法来实现这一点.例如,通过优先考虑Java应用程序或其他东西?
问题3:如何将应用程序的状态保存到文件并将其加载到内存中?
cma*_*ter 40
您的时间测量存在许多不确定性来源.所有这些来源不仅影响您的测量,而且运行时本身也是不确定的.不确定性的来源包括:
缓存使用(内存的哪些部分缓存在CPU中).CPU执行后台任务可以从缓存中清除您的数据.
内存放置(直接连接到正在执行的CPU内核的内存?).这可能会随着时间的推移而发生变化,因为您的流程可能会随时迁移到其他核心.
软件中断(您的操作系统抢占您的进程以运行不同的操作).在安静的机器上运行可以稍微减轻,但不能保证你不会被打断.
热量限制(您的CPU决定它太热并调低其时钟速度).除非你准备在一些具有固定时钟速度的嵌入式处理器上工作,否则你无能为力.
硬件中断(您的网络连接器从Internet上的另一台计算机接收到一些数据).无论什么时候,你都没有影响.
不可预测的延迟(您正在从磁盘读取一些数据,但首先,磁盘必须等到数据到达读取头下方).当您一遍又一遍地重复完全相同的操作时,这可能会遵循模式,但是一旦得到不相关的硬件中断,这可能会导致意外的延迟1/7200 rpm * 60 s/min = 8.3 ms.
垃圾收集(您询问Java,因此您在后台运行GC).即便是最好的,最现代化的垃圾收集者也不能完全避免不时地停止这个世界.即使他们没有停止世界,他们仍然在后台运行,通过缓存,内存放置和软件中断引入运行时噪声.
这些可能是最重要的来源,也可能有其他来源.关键是,您的过程永远不会在机器上独自存在.除非你在没有操作系统的情况下运行并禁用所有硬件中断,否则你必须忍受这样一个事实:你的运行时间因执行而异,并且根本无法解决这个问题.
任意代码的精确执行时间是非确定性的,因为它取决于物理机器同时执行的其他操作.
即使你计划通过跟踪启动时间戳和计划的结束时间戳并使主线程在退出程序之间的持续时间内使执行时间"恒定",它仍然会变化,这是一个相当大的数量.
线程执行或等待的时间和持续时间超出了程序员的控制范围.
[TL; DR]这是非常困难/不可能的.
更长的答案见路径加法的平面测试博士论文 - 基准方法论章节的一些问题,包括:
因此,如果您想对应用程序进行基准测试,以了解它如何以最佳方式运行:
它会让你了解最佳性能,但最佳和真实世界是两个截然不同的东西.
| 归档时间: |
|
| 查看次数: |
3741 次 |
| 最近记录: |