Unity C# 字符串操做API效率比較

先說測試結論:
操做char比string快。
string.Equals()比==快。
IndexOf()比StartWith()快不少。
LastIndexOf()比EndWith()快不少。
操做字符串時,逐個字符比較,效率會提升不少。segmentfault

IndexOf(string)和IndexOf(char)比較:

測試代碼測試

using UnityEngine;
using System.Diagnostics;

/// <summary>
/// PerformanceTest
/// ZhangYu 2019-07-27
/// <para>blog:https://segmentfault.com/u/bingfengbaidu</para>
/// </summary>
public class PerformanceTest : MonoBehaviour {

    public int times = 1;
    private Stopwatch watch = new Stopwatch();

    private void Start () {
        Test();
    }

    private void Test() {
        times = 1000000;
        FindStringTest();
    }

    private void FindStringTest() {
        string str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        IndexOfStringTest(str, ">");
        IndexOfCharTest(str, '>');
    }

    private void IndexOfStringTest(string str, string targetStr) {
        watch.Reset();
        watch.Start();
        for (int i = 0; i < times; i++) {
            str.IndexOf(targetStr);
        }
        watch.Stop();
        print("IndexOf(string):" + watch.ElapsedMilliseconds);
    }

    private void IndexOfCharTest(string str, char targetChar) {
        watch.Reset();
        watch.Start();
        for (int i = 0; i < times; i++) {
            str.IndexOf(targetChar);
        }
        watch.Stop();
        print("IndexOf(char)" + watch.ElapsedMilliseconds);
    }

}

測試結果:
IndexOf(string):160ms
IndexOf(char):100mspwa

測試結論:
查找單個字符時 IndexOf(char)比IndexOf(string)快,快37%左右。code

IndexOf(string) == 0和StartsWidth(string)比較:

測試代碼:orm

using UnityEngine;
using System;
using System.Diagnostics;

/// <summary>
/// PerformanceTest
/// ZhangYu 2019-07-27
/// <para>blog:https://segmentfault.com/u/bingfengbaidu</para>
/// </summary>
public class PerformanceTest : MonoBehaviour {

    public int times = 1;
    private Stopwatch watch = new Stopwatch();

    private void Start () {
        Test();
    }

    private void Test() {
        FindTest();
    }

    private void FindTest() {
        times = 1000000;
        string str1 = "ABCDEFGHIJKLMNOPQRSTUVWX";
        string str2 = "Test";
        IndexOfTest1(str1, str2);
        IndexOfTest2(str1, str2);
        StartWithTest1(str1, str2);
        StartWithTest2(str1, str2);
    }

    private void IndexOfTest1(string str1, string str2) {
        watch.Reset();
        watch.Start();
        for (int i = 0; i < times; i++) {
            if (str1.IndexOf(str2) == 0);
        }
        watch.Stop();
        print("str1.IndexOf(str2):" + watch.ElapsedMilliseconds);
    }

    private void IndexOfTest2(string str1, string str2) {
        watch.Reset();
        watch.Start();
        for (int i = 0; i < times; i++) {
            if (str1.IndexOf(str2, StringComparison.Ordinal) == 0);
        }
        watch.Stop();
        print("str1.IndexOf(str2, StringComparison.Ordinal):" + watch.ElapsedMilliseconds);
    }

    private void StartWithTest1(string str1, string str2) {
        watch.Reset();
        watch.Start();
        for (int i = 0; i < times; i++) {
            str1.StartsWith(str2);
        }
        watch.Stop();
        print("str1.StartsWith(str2):" + watch.ElapsedMilliseconds);
    }

    private void StartWithTest2(string str1, string str2) {
        watch.Reset();
        watch.Start();
        for (int i = 0; i < times; i++) {
            CharsStartWith(str1, str2);
        }
        watch.Stop();
        print("CharsStartWith(str1, str2):" + watch.ElapsedMilliseconds);
    }

    private bool CharsStartWith(string str1, string str2) {
        if (str2 == null) return false;
        if (str1.Length < str2.Length) return false;
        for (int i = 0; i < str2.Length; i++) {
            if (str1[i] != str2[i]) return false;
        }
        return true;
    }

}

測試結果:
str1.IndexOf(str2):153ms
str1.IndexOf(str2, StringComparison.Ordinal):167ms
str1.StartsWith(str2):1024ms
CharsStartWith(str1, str2):35msblog

測試結論:
逐個字符判斷效率最高 是IndexOf(string) == 0效率的4倍
string.StartsWith(string)效率墊底(這個API內部實現確定有多餘操做,否則不會比IndexOf(string) == 0 慢這麼多)字符串

Equals和Compare比較:

測試代碼:get

using UnityEngine;
using System;
using System.Diagnostics;

/// <summary>
/// PerformanceTest
/// ZhangYu 2019-07-27
/// <para>blog:https://segmentfault.com/u/bingfengbaidu</para>
/// </summary>
public class PerformanceTest : MonoBehaviour {

    public int times = 1;
    private Stopwatch watch = new Stopwatch();

    private void Start () {
        Test();
    }

    private void Test() {
        times = 1000000;
        CompareTest();
    }

    private void CompareTest() {
        string str1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        string str2 = "N";
        CompareTest1(str1, str2);
        CompareTest2(str1, str2);
        CompareTest3(str1, str2);
        CompareTest4(str1, str2);
        CompareTest5(str1, str2);
    }

    private void CompareTest1(string str1, string str2) {
        watch.Reset();
        watch.Start();
        for (int i = 0; i < times; i++) {
            if (str1 == str2);
        }
        watch.Stop();
        print("str1 == str2:" + watch.ElapsedMilliseconds);
    }

    private void CompareTest2(string str1, string str2) {
        watch.Reset();
        watch.Start();
        for (int i = 0; i < times; i++) {
            str1.Equals(str2);
        }
        watch.Stop();
        print("str1.Equals(str2):" + watch.ElapsedMilliseconds);
    }

    private void CompareTest3(string str1, string str2) {
        watch.Reset();
        watch.Start();
        for (int i = 0; i < times; i++) {
            string.Equals(str1, str2);
        }
        watch.Stop();
        print("string.Equals(str1, str2):" + watch.ElapsedMilliseconds);
    }

    private void CompareTest4(string str1, string str2) {
        watch.Reset();
        watch.Start();
        for (int i = 0; i < times; i++) {
            string.Compare(str1, str2);
        }
        watch.Stop();
        print("string.Compare(str1, str2):" + watch.ElapsedMilliseconds);
    }

    private void CompareTest5(string str1, string str2) {
        watch.Reset();
        watch.Start();
        StringComparison ordinal = StringComparison.Ordinal;
        for (int i = 0; i < times; i++) {
            string.Compare(str1, str2, ordinal);
        }
        watch.Stop();
        print("string.Compare(str1, str2, ordinal):" + watch.ElapsedMilliseconds);
    }

}

測試結果:
str1 == str2:26ms
str1.Equals(str2):26ms
string.Equals(str1, str2):20ms
string.Compare(str1, str2):1028ms
string.Compare(str1, str2, ordinal):48msstring

測試結論:
比較字符串時,string.Equals(str1,str2)最快,str1==str1和str1.Equals(str2)效率相同。it

EndWith和逐個字符判斷比較:

測試代碼:

using UnityEngine;
using System.Diagnostics;

/// <summary>
/// PerformanceTest
/// ZhangYu 2019-07-27
/// <para>blog:https://segmentfault.com/u/bingfengbaidu</para>
/// </summary>
public class PerformanceTest : MonoBehaviour {

    public int times = 1;
    private Stopwatch watch = new Stopwatch();

    private void Start () {
        Test();
    }

    private void Test() {
        times = 1000000;
        EndFindTest();
    }

    private void EndFindTest() {
        string str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        EndFindTest1(str, "[]");
        EndFindTest2(str, "[]");
    }

    private void EndFindTest1(string str1, string str2) {
        watch.Reset();
        watch.Start();
        for (int i = 0; i < times; i++) {
            str1.EndsWith(str2);
        }
        watch.Stop();
        print("str1.EndsWith(str2):" + watch.ElapsedMilliseconds);
    }

    private void EndFindTest2(string str1, string str2) {
        watch.Reset();
        watch.Start();
        for (int i = 0; i < times; i++) {
            CharsEndWith(str1, str2);
        }
        watch.Stop();
        print("CharsEndWith(str1, str2):" + watch.ElapsedMilliseconds);
    }

    // 逐個字符判斷str1是不是以str2結尾
    private bool CharsEndWith(string str1, string str2) {
        if (str2 == null) return false;
        if (str1.Length < str2.Length) return false;
        for (int i = 1; i <= str2.Length; i++) {
            if (str1[str1.Length - i] != str2[str2.Length - i]) return false;
        }
        return true;
    }

}

測試結果:
str1.EndsWith(str2):28480ms
CharsEndWith(str1, str2):36ms

測試結論:逐個字符判斷比EndWith(string)快多了。

相關文章
相關標籤/搜索