字符串等于字节数组比较

时间:2011-12-22 22:08:10

标签: java

字节数组比较(使用简单循环检查每个索引)比使用String.equals(Object)更快吗?我不这么认为,但是有些人似乎更喜欢基于字节的操作而不是基于字符串的操作,包括字节数组相等检查。

在侧节点上,什么时候使用字节数组而不是字符串?您是否认为例如实施Levenshtein算法来计算两个字符串的“距离”的度量。如果它基于字节而不是字符串/字符,你认为它会加速计算吗?我不这么认为,但也许。

例如,如果它用于在https://github.com/BaseXdb/basex/blob/master/src/main/java/org/basex/util/Token.java

中编码令牌

3 个答案:

答案 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