75

假设如下:

String example      = "something";
String firstLetter  = "";

以下分配方式是否存在firstLetter可能影响性能的差异?哪个最好,为什么?

firstLetter = String.valueOf(example.charAt(0));
firstLetter = Character.toString(example.charAt(0));
firstLetter = example.substring(0, 1);

第一个字母作为 a 返回的原因是String它正在 Hadoop 中运行,并且需要一个字符串来分配给一个Text类型,firstLetter它将作为key一个map()方法输出,例如:

public class FirstLetterMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
    String line = new String();
    Text firstLetter = new Text();
    IntWritable wordLength = new IntWritable();

    @Override
    public void map(LongWritable key, Text value, Context context)
            throws IOException, InterruptedException {

        line = value.toString();

        for (String word : line.split("\\W+")){
            if (word.length() > 0) {

                // ---------------------------------------------
                // firstLetter assignment
                firstLetter.set(String.valueOf(word.charAt(0)).toLowerCase());
                // ---------------------------------------------

                wordLength.set(word.length());
                context.write(firstLetter, wordLength);
            }
        }
  }
}
4

5 回答 5

118

性能方面substring(0, 1)更好,如下所示:

    String example = "something";
    String firstLetter  = "";

    long l=System.nanoTime();
    firstLetter = String.valueOf(example.charAt(0));
    System.out.println("String.valueOf: "+ (System.nanoTime()-l));

    l=System.nanoTime();
    firstLetter = Character.toString(example.charAt(0));
    System.out.println("Character.toString: "+ (System.nanoTime()-l));

    l=System.nanoTime();
    firstLetter = example.substring(0, 1);
    System.out.println("substring: "+ (System.nanoTime()-l));

输出:

String.valueOf: 38553
Character.toString: 30451
substring: 8660
于 2013-08-13T06:46:55.990 回答
14

长话短说,这可能无关紧要。使用任何你认为看起来最好的。

更长的答案,特别是使用 Oracle 的 Java 7 JDK,因为这在 JLS 中没有定义:

String.valueOfCharacter.toString以同样的方式工作,所以使用你觉得更好看的那个。其实Character.toString只是调用String.valueOfsource)。

所以问题是,你应该使用其中一个还是String.substring. 在这里,这并不重要。String.substring使用原始字符串char[],因此分配的对象少于String.valueOf. 这也可以防止原始字符串被 GC 处理,直到一个字符的字符串可用于 GC(这可能是内存泄漏),但在您的示例中,它们在每次迭代后都可用于 GC,因此不会没关系。您保存的分配也无关紧要 - achar[1]分配起来很便宜,而短期对象(就像单字符字符串一样)对于 GC 来说也很便宜。

如果你有一个足够大的数据集,这三个甚至是可测量的,substring可能会略有优势。像,真的很轻微。但是“如果...可测量”包含了这个答案的真正关键:为什么不尝试所有三个并测量哪个最快?

于 2013-08-13T05:54:37.643 回答
10
String whole = "something";
String first = whole.substring(0, 1);
System.out.println(first);
于 2017-07-04T18:53:04.740 回答
1
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;

import java.util.concurrent.TimeUnit;

@State(Scope.Thread)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Warmup(iterations = 5, time = 1)
@Fork(value = 1)
@Measurement(iterations = 5, time = 1)
public class StringFirstCharBenchmark {

    private String source;

    @Setup
    public void init() {
        source = "MALE";
    }

    @Benchmark
    public String substring() {
        return source.substring(0, 1);
    }

    @Benchmark
    public String indexOf() {
        return String.valueOf(source.indexOf(0));
    }
}

结果:

+----------------------------------------------------------------------+
| Benchmark                           Mode  Cnt   Score   Error  Units |
+----------------------------------------------------------------------+
| StringFirstCharBenchmark.indexOf    avgt    5  23.777 ? 5.788  ns/op |
| StringFirstCharBenchmark.substring  avgt    5  11.305 ? 1.411  ns/op |
+----------------------------------------------------------------------+
于 2019-05-21T13:37:44.023 回答
-6
import java.io.*;
class Initials {

    public static void main(String args[]) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String s;
        char x;
        int l;
        System.out.print("Enter any sentence: ");
        s = br.readLine();
        s = " " + s; //adding a space infront of the inputted sentence or a name
        s = s.toUpperCase(); //converting the sentence into Upper Case (Capital Letters)
        l = s.length(); //finding the length of the sentence
        System.out.print("Output = ");

        for (int i = 0; i < l; i++) {
            x = s.charAt(i); //taking out one character at a time from the sentence
            if (x == ' ') //if the character is a space, printing the next Character along with a fullstop
                System.out.print(s.charAt(i + 1) + ".");
        }
    }
}
于 2015-02-27T09:18:01.577 回答