先说测试结论:
操作char比string快。
string.Equals()比==快。
IndexOf()比StartWith()快很多。
LastIndexOf()比EndWith()快很多。
操作字符串时,逐个字符比较,效率会提高很多。
IndexOf(string)和IndexOf(char)比较:
测试代码
using UnityEngine;
using System.Diagnostics;
///
/// PerformanceTest
/// ZhangYu 2019-07-27
/// blog:https://segmentfault.com/u/bingfengbaidu
///
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):100ms
测试结论:
查找单个字符时 IndexOf(char)比IndexOf(string)快,快37%左右。
IndexOf(string) == 0和StartsWidth(string)比较:
测试代码:
using UnityEngine;
using System;
using System.Diagnostics;
///
/// PerformanceTest
/// ZhangYu 2019-07-27
/// blog:https://segmentfault.com/u/bingfengbaidu
///
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):35ms
测试结论:
逐个字符判断效率最高 是IndexOf(string) == 0效率的4倍
string.StartsWith(string)效率垫底(这个API内部实现肯定有多余操作,不然不会比IndexOf(string) == 0 慢这么多)
Equals和Compare比较:
测试代码:
using UnityEngine;
using System;
using System.Diagnostics;
///
/// PerformanceTest
/// ZhangYu 2019-07-27
/// blog:https://segmentfault.com/u/bingfengbaidu
///
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):48ms
测试结论:
比较字符串时,string.Equals(str1,str2)最快,str1==str1和str1.Equals(str2)效率相同。
EndWith和逐个字符判断比较:
测试代码:
using UnityEngine;
using System.Diagnostics;
///
/// PerformanceTest
/// ZhangYu 2019-07-27
/// blog:https://segmentfault.com/u/bingfengbaidu
///
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)快多了。