gpt4 book ai didi

java - 为什么 Java String.indexOf() 优于用户定义类中实现的相同逻辑?

转载 作者:行者123 更新时间:2023-11-29 07:47:33 25 4
gpt4 key购买 nike

我对 Java 的 String.indexOf(String subString) 的性能有疑问。

我编写了一个类来比较调用 String.indexOf(String subString) 与从 String 的源代码内部复制源代码并使用完全相同的参数调用内部 indexOf() 的性能。

当直接调用 String.indexOf() 时,性能似乎提高了大约 4 倍,尽管调用堆栈会深 2 帧。

我的 JVM 是 JDK1.7.0_40 64 位(windows 热点)。我的机器运行的是带有 i7-4600U CPU 和 16GB 内存的 Windows。

代码如下:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;

public class TestIndexOf implements Runnable {

final static String s0 = "This is my search string, it is pretty long so can test the speed of the search";
final static String s1 = "speed of the search";
final static char[] c0 = s0.toCharArray();
final static char[] c1 = s1.toCharArray();
final static byte[] b0 = s0.getBytes();
final static byte[] b1 = s1.getBytes();

static AtomicBoolean EXIT = new AtomicBoolean(false);
static AtomicLong TOTAL = new AtomicLong(0);

@Override
public void run() {
long count = 0;
try {
for (;;) {
// Case 1, search as byte[]
int idx = indexOf(b0, 0, b0.length, b1, 0, b1.length, 0);
// Case 2, search as char[]
// int idx = indexOf(c0, 0, c0.length, c1, 0, c1.length, 0);
// Case 3, search as String (using String.indexOf())
// int idx = s0.indexOf(s1);
if (idx >= 0) {
count ++;
}
if (EXIT.get()) {
break;
}
}
TOTAL.addAndGet(count);
} catch(Exception e) {
e.printStackTrace();
}
}

/* byte version of indexOf, modified from Java JDK source */
static int indexOf(byte[] source, int sourceOffset, int sourceCount,
byte[] target, int targetOffset, int targetCount,
int fromIndex) {
if (fromIndex >= sourceCount) {
return (targetCount == 0 ? sourceCount : -1);
}
if (fromIndex < 0) {
fromIndex = 0;
}
if (targetCount == 0) {
return fromIndex;
}

byte first = target[targetOffset];
int max = sourceOffset + (sourceCount - targetCount);

for (int i = sourceOffset + fromIndex; i <= max; i++) {
/* Look for first character. */
if (source[i] != first) {
while (++i <= max && source[i] != first) {
;
}
}

/* Found first character, now look at the rest of v2 */
if (i <= max) {
int j = i + 1;
int end = j + targetCount - 1;
for (int k = targetOffset + 1; j < end && source[j] ==
target[k]; j++, k++) {
;
}

if (j == end) {
/* Found whole string. */
return i - sourceOffset;
}
}
}
return -1;
}

/* char version of indexOf, directly copied from JDK's String class */
static int indexOf(char[] source, int sourceOffset, int sourceCount,
char[] target, int targetOffset, int targetCount,
int fromIndex) {
if (fromIndex >= sourceCount) {
return (targetCount == 0 ? sourceCount : -1);
}
if (fromIndex < 0) {
fromIndex = 0;
}
if (targetCount == 0) {
return fromIndex;
}

char first = target[targetOffset];
int max = sourceOffset + (sourceCount - targetCount);

for (int i = sourceOffset + fromIndex; i <= max; i++) {
/* Look for first character. */
if (source[i] != first) {
while (++i <= max && source[i] != first) {
;
}
}

/* Found first character, now look at the rest of v2 */
if (i <= max) {
int j = i + 1;
int end = j + targetCount - 1;
for (int k = targetOffset + 1; j < end && source[j] ==
target[k]; j++, k++) {
;
}

if (j == end) {
/* Found whole string. */
return i - sourceOffset;
}
}
}
return -1;
}


public static void main(String[] args) throws Exception {
int threads = 4;
ExecutorService executorService = Executors.newFixedThreadPool(threads);
for(int i=0; i<threads; i++) {
executorService.execute(new TestIndexOf());
}
Thread.sleep(10000);
EXIT.set(true);
System.out.println("STOPPED");
Thread.sleep(1000);
System.out.println("Count = " + TOTAL.get());
System.exit(0);
}
}

我得到的结果是:(2 个样本,运行 10 秒,有 4 个线程)

字节[]224848726225011695

字符[]224707442224707442

字符串898161092897897572

String.indexOf() 有什么神奇之处?这会获得硬件加速吗? :P

最佳答案

JVM 对标准库中的一些方法进行了特定的优化。其中之一将用高效的内联汇编替换对 String.indexOf 的调用。它甚至可以利用 SSE4.2 instructions .这很可能导致这种差异。

详情请见:src/share/vm/opto/library_call.cpp

关于java - 为什么 Java String.indexOf() 优于用户定义类中实现的相同逻辑?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24256232/

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