2011-12-22 88 views
1

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

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

举例来说,如果它是用来编码令牌作为https://github.com/BaseXdb/basex/blob/master/src/main/java/org/basex/util/Token.java

+1

如果没有记错,字符串和一个字节数组是两个独立的东西,字符是UCS-2或UTF-16或东西。如果是这样,你问烤面包机是否比食品加工者快。 – 2011-12-22 22:11:40

+1

@在我看来,你的比喻有点偏离。 Java'char'没有什么特别之处。他们只是无符号的16位整数,没有什么更多,没有什么。 – corsiKa 2011-12-22 22:14:14

+0

它们仍然不同于字节。 – EJP 2011-12-23 03:13:05

回答

8

字符串不包含字节。它们包含字符。而字符串等于明显地比较了两个字符串的字符(除非它们甚至没有相同的长度)。由于String可以直接访问底层字符数组,而外部代码没有,所以使用equals明显更快。

处理二进制数据(二进制流,密码等)时使用字节数组是有意义的。处理文本数据时,使用Strings,StringBuilders,CharSequence或char数组更好。这完全取决于情况。

+0

是的,我知道它是不一样的,我想知道,如果你转换为例如标记,如在https://github.com/BaseXdb/basex/blob/master/src/main/java/org/ basex/util/Token.java – Johannes 2011-12-22 22:17:14

+2

为什么要将整个字符串复制到字节数组中以进行比较?这只是没有意义。当写入流(文件,套接字等)时,字符串必须转换为字节。 IO作家是为此而写的。 – 2011-12-22 22:22:20

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

你的方法很简单,所以当然会给出这些结果。 Java中的字符串是不可变的对象,因此它们可以进行很好的优化。其中一种优化是他们的哈希码是预先计算的。比较两个字符串时,首先比较它们的哈希码,如果它们不同,则会跳过实际字符的比较,因为事先知道它会失败。为了做一个真正的测试,你将不得不编写一个封装了字节数组的新类,像字符串那样表现为不可变对象,并且包含相同类型的优化。 – 2011-12-22 23:15:22

+0

严格地说,字节数组之间的字节比较(这是OP要求的)不会比字符串比较快。但是,那么这种用法会很幼稚。 – 2011-12-22 23:21:47

+0

@MikeNakis:这种方法是OP所问的。它比OP建议的更快,因为它没有考虑在比较字节数组之前将字符串转换为字节所花费的时间。 – 2011-12-23 07:35:29