jvm 《七》对Java HotSpot VM进行基准测试 or 为什么HotSpot不能让我的图形代码变得更快?

我写了一个简单的循环来计算一个简单的操作,

我要研究一下他为啥这么慢?

public class Benchmark {

public static void main(String[] arg) {

long before = System.currentTimeMillis();

int sum = 0;

for (int index = 0; index < 10*1000*1000; index += 1) {

sum += index;

}

long after = System.currentTimeMillis();

System.out.println("Elapsed time: " +

Long.toString(after - before) +

" milliseconds");

}

}


HotSpot的工作原理:

       它首先使用解释器运行程序。当它发现某些方法是“热”时 - 也就是说,执行了很多,要么因为它被调用很多,要么因为它包含循环很多的循环 - 它会发送该方法以进行编译。之后,将发生两件事之一,或者在下次调用该方法时,将调用编译版本(而不是解释版本),或者使用编译方法替换当前长时间运行的循环,同时仍在运行。后者被称为“堆栈替换”或OSR。

同时,如果你坚持使用/编写这样的微基准,你可以通过将main的主体移动到一个新方法并从main调用一次来给编译器编译代码的机会,然后调用它再次出现在计时器中,看看HotSpot的速度有多快。

另请参阅JavaOne 2002演示文稿 S-1816如何不编写Microbenchmark

我正在尝试计算方法调用时间。我不希望有任何额外的工作,所以我使用一个空方法。但是当我使用HotSpot运行时,我得到的速度令人难以置信。这是我的代码:

public class EmptyMethod {

public static void method() {

}

public static void runTest() {

long before;

long after;

// First, figure out the time for an empty loop

before = System.currentTimeMillis();

for (int index = 0; index < 1*1000*1000; index += 1) {

}

after = System.currentTimeMillis();

long loopTime = after - before;

System.out.println("Loop time: " +

Long.toString(loopTime) +

" milliseconds");

// Then time the method call in the loop

before = System.currentTimeMillis();

for (int index = 0; index < 1*1000*1000; index += 1) {

method();

}

after = System.currentTimeMillis();

long methodTime = after - before;

System.out.println("Method time: " +

Long.toString(methodTime) +

" milliseconds");

System.out.println("Method time - Loop time: " +

Long.toString(methodTime - loopTime) +

" milliseconds");

}

public static void main(String[] arg) {

// Warm up the virtual machine, and time it

runTest();

runTest();

runTest();

}

}


空方法不计算在内。而且您还看到生成的代码对齐对象非常敏感。

对空方法的调用正在被内联,因此实际上没有时间调用。编译器在其调用站点将内联小方法。这减少了对小方法的调用的开销。这对于用于提供数据抽象的访问器方法特别有用。如果该方法实际为空,则内联将完全删除该调用。

代码生成到内存中并从那里执行。代码在内存中的布局方式对其执行方式有很大影响。在我的机器上的这个例子中,声称调用该方法的循环更好地对齐,因此比试图计算运行空循环所需多长时间的循环运行得更快,所以我得到负数 methodTime-loopTime。

好的,所以我会在方法的主体中放入一些随机代码,因此它不是空的,并且内联不能只删除它。这是我的新方法(并且调用站点更改为调用方法(17)):

public static void method(int arg){

int value = arg + 25;

}


HotSpot编译器足够智能,不会为死变量生成代码。

在上面的方法中,从不使用局部变量,因此没有理由计算其值。因此,方法体再次为空,当代码被编译时(并且内联,因为我们删除了足够小的代码以便内联),它又变成了一个空方法。

对于那些不习惯处理优化编译器的人来说,这可能是令人惊讶的,因为他们可以非常聪明地发现和消除死代码。它们偶尔可能相当愚蠢,所以不要指望编译器对代码进行任意优化。

死代码消除也扩展到控制流程。如果编译器可以在测试中看到特定的“变量”实际上是常量,则可以选择不编译永远不会执行的分支的代码。这使得微基准测试“足够棘手”以实际计算您认为您的计时时间变得棘手。

死代码消除在实际代码中非常有用。并不是说人们故意写死代码; 但是,由于内联常常(例如,方法的实际参数)替换变量,使得某些控制流失效,编译器通常会发现死代码。

我正在尝试对对象分配和垃圾收集进行基准测试。所以我有上面的那个,但方法的主体是:

public static void method(){

Object o = new Object();

}


这是HotSpot存储管理器的最佳案例。你会得到不切实际的数字。

您正在分配不需要初始化的对象,并立即将它们放在地板上。(不,编译器不够聪明,无法优化分配。)真正的程序确实分配了相当数量的短期临时对象,但它们也比这个简单的测试程序更长时间地保留了一些对象。HotSpot存储管理器为保留更长时间的对象执行更多工作,因此请注意尝试将此类测试中的数字扩展到实际系统。

我有一个图形密集型或基于GUI的程序。为什么HotSpot不能让我的图形代码变得更快?

图形程序将大量时间花在本机库中。

Java应用程序的整体性能取决于四个因素:

应用程序的设计

虚拟机执行Java字节码的速度

执行基本功能任务的库执行的速度(以本机代码表示)

底层硬件和操作系统的速度

虚拟机负责字节代码执行,存储分配,线程同步等。与虚拟机一起运行的是本机代码库,它们通过操作系统处理输入和输出,尤其是通过窗口系统的图形操作。在这些本机代码库中花费大量时间的程序将不会看到它们在HotSpot上的性能提高与花费大部分时间执行字节代码的程序一样多。

关于本机代码的这种观察适用于您恰好与应用程序一起使用的其他本​​机库或任何本机代码库。

您对HotSpot或任何虚拟机进行基准测试的建议

这里最好的答案是使用真实的应用程序进行基准测试,因为它们是唯一能够产生真正差异的应用程序。如果无法做到这一点,请使用标准SPEC基准测试,然后使用其他备受推崇的行业基准测试。应避免使用微量标记,或至少要谨慎使用。微基准测试由于优化效果而给出误导性答案是很常见的。


---------------------

作者:a_Ygygs_Dxdsr_XdMss

来源:CSDN

原文:https://blog.csdn.net/weixin_42749765/article/details/87454013

版权声明:本文为博主原创文章,转载请附上博文链接!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容