Tôi chạy vào một hiệu suất lạ "tạo tác" với String.StartsWith.Hiệu suất của String.StartsBằng cách sử dụng StringComparison.OrdinalIgnoreCase
Có vẻ như String.StartsWith sử dụng OrdinalIgnoreCase nhanh hơn sử dụng String.StartsWith mà không chỉ định StringComparison. (2-4x nhanh hơn)
Tuy nhiên, việc kiểm tra bình đẳng sẽ nhanh hơn khi sử dụng String.Equals không có StringComparison so với khi sử dụng OrdinalIgnoreCase. (Mặc dù tất cả đều có cùng tốc độ)
Câu hỏi đặt ra là tại sao? Tại sao họ thực hiện khác nhau trong hai trường hợp?
Đây là mã tôi đã sử dụng:
public static void Test()
{
var options = new[] { "asd/klfe", "qer/jlkfe", "p33/ji", "fkjlfe", "asd/23", "bleash", "quazim", "ujv/3", "jvd/kfl" };
Random r;
const int trialSize = 100000;
const int trials = 1000;
Stopwatch swEqOp = new Stopwatch();
Stopwatch swEq = new Stopwatch();
Stopwatch swEqOrdinal = new Stopwatch();
Stopwatch swStartsWith = new Stopwatch();
Stopwatch swStartsWithOrdinal = new Stopwatch();
for (int i = 0; i < trials; i++)
{
{
r = new Random(1);
swEqOp.Start();
for (int j = 0; j < trialSize; j++)
{
bool result = options[r.Next(options.Length)] == "asd/klfe";
}
swEqOp.Stop();
}
{
r = new Random(1);
swEq.Start();
for (int j = 0; j < trialSize; j++)
{
bool result = string.Equals(options[r.Next(options.Length)], "asd/klfe");
}
swEq.Stop();
}
{
r = new Random(1);
swEqOrdinal.Start();
for (int j = 0; j < trialSize; j++)
{
bool result = string.Equals(options[r.Next(options.Length)], "asd/klfe", StringComparison.OrdinalIgnoreCase);
}
swEqOrdinal.Stop();
}
{
r = new Random(1);
swStartsWith.Start();
for (int j = 0; j < trialSize; j++)
{
bool result = options[r.Next(options.Length)].StartsWith("asd/");
}
swStartsWith.Stop();
}
{
r = new Random(1);
swStartsWithOrdinal.Start();
for (int j = 0; j < trialSize; j++)
{
bool result = options[r.Next(options.Length)].StartsWith("asd/",StringComparison.OrdinalIgnoreCase);
}
swStartsWithOrdinal.Stop();
}
}
//DEBUG with debugger attached. Release without debugger attached. AnyCPU both cases.
//DEBUG : 1.54 RELEASE : 1.359
Console.WriteLine("Equals Operator: " + swEqOp.ElapsedMilliseconds/1000d);
//DEBUG : 1.498 RELEASE : 1.349 <======= FASTEST EQUALS
Console.WriteLine("String.Equals: " + swEq.ElapsedMilliseconds/1000d);
//DEBUG : 1.572 RELEASE : 1.405
Console.WriteLine("String.Equals OrdinalIgnoreCase: " + swEqOrdinal.ElapsedMilliseconds/1000d);
//DEBUG : 14.234 RELEASE : 9.914
Console.WriteLine("String.StartsWith: " + swStartsWith.ElapsedMilliseconds/1000d);
//DEBUG : 7.956 RELEASE : 3.953 <======= FASTEST StartsWith
Console.WriteLine("String.StartsWith OrdinalIgnoreCase: " + swStartsWithOrdinal.ElapsedMilliseconds/1000d);
}
Tôi có thể hiểu tại sao nó sẽ nhanh hơn với Ordinal - Tôi không hiểu tại sao String.Equals hoạt động khác ... – MineR
OK, vì vậy khi nhìn vào String.Equals, nó không thực sự sử dụng StringComparison nếu không có được chỉ định - thay vào đó nó sử dụng một triển khai cụ thể. – MineR