字节数组比较(使用简单循环检查每个索引)比使用String.equals(Object)
更快吗?我不这么认为,但是有些人似乎更喜欢基于字节的操作而不是基于字符串的操作,包括字节数组相等检查。
在侧节点上,什么时候使用字节数组而不是字符串?您是否认为例如实施Levenshtein算法来计算两个字符串的“距离”的度量。如果它基于字节而不是字符串/字符,你认为它会加速计算吗?我不这么认为,但也许。
例如,如果它用于在https://github.com/BaseXdb/basex/blob/master/src/main/java/org/basex/util/Token.java
中编码令牌答案 0 :(得分:9)
字符串不包含字节。它们包含字符。 String等于显然比较两个字符串的字符(除非它们甚至没有相同的长度)。由于String可以直接访问底层char数组,而外部代码没有,因此使用equals
显然更快。
在处理二进制数据(二进制流,加密等)时使用字节数组是有意义的。处理文本数据时,使用Strings,StringBuilders,CharSequence或char数组会更好。这一切都取决于具体情况。
答案 1 :(得分:0)
我写了一个小测试来看,而不是猜测:
import java.util.Arrays;
import java.util.Random;
public class StringComparisons {
static String[] strings = new String[10000];
static byte[][] bytes = new byte[10000][];
public static void main(String[] args) {
Random r = new Random();
System.out.println("Generating strings/byte arrays");
for (int i = 0; i < strings.length; i++) {
StringBuilder s = new StringBuilder();
for (int j = 0; j < 1000; j++) {
s.append(r.nextInt(128) + 1);
}
strings[i] = s.toString();
bytes[i] = strings[i].getBytes();
}
final String comparend = strings[r.nextInt(strings.length)];
final byte[] byteComparend = comparend.getBytes();
System.out.println("Comparing strings...");
long start = System.nanoTime();
for (int i = 0; i < strings.length; i++) {
comparend.equals(strings[i]);
}
long elapsed = System.nanoTime() - start;
System.out.printf("Comparing strings took %f s\n", (elapsed / 1000000000.0));
System.out.println("Comparing byte arrays");
start = System.nanoTime();
for (int i = 0; i < bytes.length; i++) {
Arrays.equals(byteComparend, bytes[i]);
}
elapsed = System.nanoTime() - start;
System.out.printf("Comparing bytes took %f s\n", (elapsed / 1000000000.0));
}
}
字符串比较似乎要快几个数量级。
我机器上的示例输出是:
Generating strings/byte arrays
Comparing strings...
Comparing strings took 0.000010 s
Comparing byte arrays
Comparing bytes took 0.001339 s
答案 2 :(得分:0)
您可以将 JMH 用于此类基准测试。以下是您问题的示例
@BenchmarkMode({ Mode.AverageTime, Mode.Throughput })
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Warmup(iterations = 3, time = 5)
@Measurement(iterations = 5, time = 10)
@Threads(1)
@State(Scope.Benchmark)
public class StringVsBytesComparison {
String s1 = "Hello";
String s2 = "Hello";
@Benchmark
public boolean stringComparison() {
String s1 = "Hello";
String s2 = "Hello";
return s1.equals(s2);
}
@Benchmark
public boolean bytesComparison() {
byte[] ba1 = s1.getBytes();
byte[] ba2 = s2.getBytes();
return Arrays.equals(ba1, ba2);
}
}
输出
Benchmark Mode Cnt Score Error Units
StringVsBytesComparison.bytesComparison thrpt 5 0.011 ± 0.001 ops/ns
StringVsBytesComparison.stringComparison thrpt 5 0.466 ± 0.010 ops/ns
StringVsBytesComparison.bytesComparison avgt 5 90.547 ± 3.312 ns/op
StringVsBytesComparison.stringComparison avgt 5 2.166 ± 0.062 ns/op
很明显,字符串比较获胜。 请找到完整的源代码here