Java字符串拼接、數字轉換字符串性能測試與優化方案


Java的字符串拼接問題已經是老生常談的問題了,目前遇到一個業務場景是,在游戲底層新使用了一套事件監聽的組件,字符串作為事件的條件值,所以需要較為頻繁的拼接和將數字轉換為字符串,去匹配事件監聽的條件。在條件值已知有限的情況下,可不可以通過空間換時間的方式,用HashMap緩存條件對應字符串的關系,去優化頻繁字符串拼接與轉換的執行效率?測試如下:

測試1:字符串拼接

public class TestString {

    public static long startMs;
    
    
    public static void main(String[] args) {
        testStringBuilder();
        testCache();
    }

    public static void testStringBuilder() {
        TestString testString = new TestString();
        String className = testString.getClass().getSimpleName();
        int max = 10000000;
        // 開始計時
        startMs = System.currentTimeMillis();
        for (int b = 0; b <= max / 10000; b++) {
            for (int i = 0; i < 10000; i++) {
                String s = className + i;
                doSomething(s);
            }
        }
        System.out.println("testStringBuilder結束,循環次數:" + max + ",耗時:" + (System.currentTimeMillis() - startMs) + "ms");
    }

    public static void testCache() {
        Map<Class<?>, Map<Integer, String>> cache = new HashMap<>();
        Map<Integer, String> temp = new HashMap<>();
        Class<?> testClass = TestString.class;
        int max = 10000000;
        for (int i = 0; i < 10000; i++) {
            String s = testClass.getSimpleName() + i;
            temp.put(i, s);
        }
        cache.put(testClass, temp);
        // 開始計時
        startMs = System.currentTimeMillis();
        for (int b = 0; b <= max / 10000; b++) {
            for (int i = 0; i < 10000; i++) {
                String s = cache.get(testClass).get(i);
                doSomething(s);
            }
        }
        System.out.println("testCache結束,循環次數:" + max + ",耗時:" + (System.currentTimeMillis() - startMs) + "ms");
    }

    public static void doSomething(String result) {
        // System.out.println(result);
    }

}

假定條件樣本為1萬份不重復,循環1千萬次字符串拼接/Map獲取操作。JDK8中,通過+號的方式動態的拼接字符串,會被編譯器優化為StringBuilder.append()方法,是效率較高的字符串拼接方式。 多次運行,平均結果如下:

通過HashMap緩存映射關系比每次都去拼接字符串執行速度快了差不讀4倍,還是比較明顯的

測試2:數字轉換為字符串

public class TestString2 {

    public static long startMs;

    public static void main(String[] args) {
        testIntegerToString();
        testCacheMap();
    }

    public static void testIntegerToString() {
        int max = 10000000;
        startMs = System.currentTimeMillis();
        for (int b = 0; b <= max / 10000; b++) {
            for (int i = 0; i < 10000; i++) {
                String s = Integer.toString(i);
                // String s = String.valueOf(i); 方法內部也是調用Integer.toString方法
                doSomething(s);
            }
        }
        System.out.println("testToString結束,循環次數:" + max + ",耗時:" + (System.currentTimeMillis() - startMs) + "ms");
    }

    public static void testCacheMap() {
        Map<Integer, String> temp = new HashMap<>();
        int max = 10000000;
        for (int i = 0; i < 10000; i++) {
            String s = Integer.toString(i);
            temp.put(i, s);
        }
        // ========== 開始計時 ==========
        startMs = System.currentTimeMillis();
        for (int b = 0; b <= max / 10000; b++) {
            for (int i = 0; i < 10000; i++) {
                String s = temp.get(i);
                doSomething(s);
            }
        }
        System.out.println("testCache結束,循環次數:" + max + ",耗時:" + (System.currentTimeMillis() - startMs) + "ms");
    }

    public static void doSomething(String result) {
        // System.out.println(result);
    }

}

假定條件樣本為1萬份不重復,循環1千萬次對1到10000的數字轉換為字符串的操作/Map獲取操作。Integer.toString(i)的方式與String.valueOf(i)的方式相同,String.valueOf方法內部也是調用的Integer.toString方法。多次運行,平均結果如下:

 可以看出執行效率相差也是比較多的,執行速度大約相差了2.5倍。

結論

Hash算法確實是很快,如果業務場景需要拼接或轉換為字符串的操作特別頻繁,要拼接字符串的基本字符串有一定規則、可以窮舉,並且內存大小在可承受的范圍內時,可以采用多級Hash提前緩存映射關系,可以大程度提升執行速度,是典型的空間換時間。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM