gpt4 book ai didi

java - jvm如何优化循环代码?

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:27:46 24 4
gpt4 key购买 nike

有一种方法可以从文本中搜索子串(使用暴力算法,请忽略空指针)

public static int forceSearch(String text, String pattern) {
int patternLength = pattern.length();
int textLength = text.length();

for (int i = 0, n = textLength - patternLength; i <= n; i++) {
int j = 0;
for (; j < patternLength && text.charAt(i + j) == pattern.charAt(j); j++) {
;
}
if (j == patternLength) {
return i;
}
}
return -1;
}

奇怪!使用相同的算法,但下面的代码更快!!!

public static int forceSearch(String text, String pattern) {
int patternLength = pattern.length();
int textLength = text.length();

char first = pattern.charAt(0);
for (int i = 0, n = textLength - patternLength; i <= n; i++) {
if (text.charAt(i) != first) {
while (++i <= n && text.charAt(i) != first)
;
}

int j = 0;
for (; j < patternLength && text.charAt(i + j) == pattern.charAt(j); j++) {
;
}
if (j == patternLength) {
return i;
}
}
return -1;
}

我发现如果我用 jvm 运行第二个代码明显比第一个快。但是,当我用 c 编写并运行时,这两个函数花费的时间几乎相同。所以我认为原因是jvm优化了循环代码

if (text.charAt(i) != first) {
while (++i <= max && text.charAt(i) != first)
;
}

我说的对吗?如果我是对的,我们应该如何使用jvm优化策略来 优化我们的代码?

希望有人帮忙,谢谢:)

最佳答案

如果您真的想深入了解这个问题,您可能需要指示 JVM 打印程序集。根据我的经验,对循环进行微小的调整可能会导致令人惊讶的性能差异。但这不一定是由于循环本身的优化。

有很多因素会影响代码的 JIT 编译方式。例如,调整方法的大小会影响您的内联树,这可能意味着更好或更差的性能,具体取决于您的调用堆栈的外观。如果一个方法被内联到调用堆栈的更深处,它可能会阻止嵌套的调用站点被内联到同一个框架中。如果那些嵌套的调用站点特别“热门”,那么增加的调用开销可能会很大。我并不是说那是这里的原因;我只是指出,有许多阈值可以控制 JIT 如何安排您的代码,并且性能差异的原因并不总是很明显。

将 JMH 用于基准测试的一个好处是,您可以通过显式设置内联边界来减少此类更改的影响。但是您可以使用 -XX:CompileCommand 手动实现相同的效果。

当然,还有缓存友好性等其他因素需要更直观的分析。鉴于您的基准测试可能 没有特别深的调用树,我倾向于倾向于将缓存行为作为更可能的解释。我猜你的第二个版本性能更好,因为你的比较(pattern 的第一 block )通常在你的 L1 缓存中,而你的第一个版本会导致更多的缓存流失。如果您的输入很长(听起来很长),那么这可能是一种解释。如果不是,原因可能更微妙,例如,您的第一个版本可能是“欺骗”CPU 使用更积极的缓存预取,但实际上损害性能(至少对于输入你正在做基准测试)。无论如何,如果要解释缓存行为,那么我想知道为什么您在 C 版本中看不到类似的差异。您在编译 C 版本时使用了哪些优化标志?

消除死代码也可能是一个因素。我必须看看您的输入是什么,但您的手动优化版本可能会导致某些指令 block 在检测解释阶段永远不会被命中,从而导致 JIT 将它们排除在最终组装之外。

我重申:如果您想查明真相,您需要强制 JIT 转储每个版本的程序集(并与 C 版本进行比较)。

关于java - jvm如何优化循环代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50185660/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com