Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

charAt() or substring? Which is faster?

I want to go through each character in a String and pass each character of the String as a String to another function.

String s = "abcdefg";
for(int i = 0; i < s.length(); i++){
    newFunction(s.substring(i, i+1));}

or

String s = "abcdefg";
for(int i = 0; i < s.length(); i++){
    newFunction(Character.toString(s.charAt(i)));}

The final result needs to be a String. So any idea which will be faster or more efficient?

like image 793
estacado Avatar asked Nov 04 '09 08:11

estacado


People also ask

What is the difference between charAt and substring?

Differentiate between charAt() and substring()It extracts a part of the string as specified by its arguments and returns the extracted part as a new string. Example: String str = "Hello"; char ch = str.

Is substring faster than replace?

As expected, the substring is fastest because: It avoids compiling a regular expression.

Is substring fast Java?

substring() is blazingly fast. The only thing that would be faster still is to avoid object creation completely by keeping track of the substring start and end positions in variables.

What can I use instead of charAt?

Just use Array. from to turn the string into an array.


2 Answers

As usual: it doesn't matter but if you insist on spending time on micro-optimization or if you really like to optimize for your very special use case, try this:

import org.junit.Assert;
import org.junit.Test;

public class StringCharTest {

    // Times:
    // 1. Initialization of "s" outside the loop
    // 2. Init of "s" inside the loop
    // 3. newFunction() actually checks the string length,
    // so the function will not be optimized away by the hotstop compiler

    @Test
    // Fastest: 237ms / 562ms / 2434ms
    public void testCacheStrings() throws Exception {
        // Cache all possible Char strings
        String[] char2string = new String[Character.MAX_VALUE];
        for (char i = Character.MIN_VALUE; i < Character.MAX_VALUE; i++) {
            char2string[i] = Character.toString(i);
        }

        for (int x = 0; x < 10000000; x++) {
            char[] s = "abcdefg".toCharArray();
            for (int i = 0; i < s.length; i++) {
                newFunction(char2string[s[i]]);
            }
        }
    }

    @Test
    // Fast: 1687ms / 1725ms / 3382ms
    public void testCharToString() throws Exception {
        for (int x = 0; x < 10000000; x++) {
            String s = "abcdefg";
            for (int i = 0; i < s.length(); i++) {
                // Fast: Creates new String objects, but does not copy an array
                newFunction(Character.toString(s.charAt(i)));
            }
        }
    }

    @Test
    // Very fast: 1331 ms/ 1414ms / 3190ms
    public void testSubstring() throws Exception {
        for (int x = 0; x < 10000000; x++) {
            String s = "abcdefg";
            for (int i = 0; i < s.length(); i++) {
                // The fastest! Reuses the internal char array
                newFunction(s.substring(i, i + 1));
            }
        }
    }

    @Test
    // Slowest: 2525ms / 2961ms / 4703ms
    public void testNewString() throws Exception {
        char[] value = new char[1];
        for (int x = 0; x < 10000000; x++) {
            char[] s = "abcdefg".toCharArray();
            for (int i = 0; i < s.length; i++) {
                value[0] = s[i];
                // Slow! Copies the array
                newFunction(new String(value));
            }
        }
    }

    private void newFunction(String string) {
        // Do something with the one-character string
        Assert.assertEquals(1, string.length());
    }

}
like image 136
mhaller Avatar answered Nov 15 '22 21:11

mhaller


The answer is: it doesn't matter.

Profile your code. Is this your bottleneck?

like image 31
Will Avatar answered Nov 15 '22 19:11

Will