upper/lower - C# string大小写转换函数性能比较

C#的string类中,包含ToUpper/ToLower以及ToUpperInvariant/ToLowerInvariant大小写转换函数

upper/lower - C# string大小写转换函数性能比较

1 Prototype

Definition of ToUpper/ToLower/ToUpperInvariant/ToLowerInvariant methods in string class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
//
// Summary:
// Returns a copy of this string converted to lowercase.
//
// Returns:
// A string in lowercase.
public String ToLower();
//
// Summary:
// Returns a copy of this string converted to lowercase, using the casing rules
// of the specified culture.
//
// Parameters:
// culture:
// An object that supplies culture-specific casing rules.
//
// Returns:
// The lowercase equivalent of the current string.
//
// Exceptions:
// T:System.ArgumentNullException:
// culture is null.
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
public String ToLower(CultureInfo culture);
//
// Summary:
// Returns a copy of this System.String object converted to lowercase using the
// casing rules of the invariant culture.
//
// Returns:
// The lowercase equivalent of the current string.
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
public String ToLowerInvariant();


// ...


//
// Summary:
// Returns a copy of this string converted to uppercase.
//
// Returns:
// The uppercase equivalent of the current string.
public String ToUpper();
//
// Summary:
// Returns a copy of this string converted to uppercase, using the casing rules
// of the specified culture.
//
// Parameters:
// culture:
// An object that supplies culture-specific casing rules.
//
// Returns:
// The uppercase equivalent of the current string.
//
// Exceptions:
// T:System.ArgumentNullException:
// culture is null.
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
public String ToUpper(CultureInfo culture);
//
// Summary:
// Returns a copy of this System.String object converted to uppercase using the
// casing rules of the invariant culture.
//
// Returns:
// The uppercase equivalent of the current string.
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
public String ToUpperInvariant();


reference .NET Reference Source - Mircosoft for more.

2 Program

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;

namespace UpperLowerTest
{
public static class Program
{
static void Main(string[] args)
{
Stopwatch stopwatch = new Stopwatch();

// read EN strings from file
stopwatch.Start();
List<string> strings = ReadStrings("test.html");
stopwatch.Stop();
Console.WriteLine("line count: {0}\nReadString: {1}ms", strings.Count, stopwatch.ElapsedMilliseconds);

// test ToUpper
stopwatch.Start();
List<string> toUpperStrings = ToUpperTest(strings);
stopwatch.Stop();
Console.WriteLine("line count: {0}\tToUpperTest: {1}ms", toUpperStrings.Count, stopwatch.ElapsedMilliseconds);

// test ToUpperInvariant
stopwatch.Start();
List<string> toUpperInvariantStrings = ToUpperInvariantTest(strings);
stopwatch.Stop();
Console.WriteLine("line count: {0}\tToUpperInvariantTest: {1}ms", toUpperStrings.Count, stopwatch.ElapsedMilliseconds);

// test ToLower
stopwatch.Start();
List<string> toLowerStrings = ToLowerTest(strings);
stopwatch.Stop();
Console.WriteLine("line count: {0}\tToLowerTest: {1}ms", toUpperStrings.Count, stopwatch.ElapsedMilliseconds);

// test ToLowerInvariant
stopwatch.Start();
List<string> toLowerInvariantStrings = ToLowerInvariantTest(strings);
stopwatch.Stop();
Console.WriteLine("line count: {0}\tToLowerInvariantTest: {1}ms", toUpperStrings.Count, stopwatch.ElapsedMilliseconds);

stopwatch.Start();
WriteStrings(toUpperStrings, "toUpperStrings.html");
WriteStrings(toUpperInvariantStrings, "toUpperInvariantStrings.html");
WriteStrings(toLowerStrings, "toLowerStrings.html");
WriteStrings(toLowerInvariantStrings, "toLowerInvariantStrings.html");
Console.WriteLine("WriteStrings: {0}ms", stopwatch.ElapsedMilliseconds);
}

public static List<string> ReadStrings(string path)
{
StreamReader streamReader = new StreamReader(path);
string line;
List<string> stringList = new List<string>();

while(!streamReader.EndOfStream)
{
line = streamReader.ReadLine();
stringList.Add(line);
}

streamReader.Close();
return stringList;
}

public static List<string> WriteStrings(List<string> stringList, string path)
{
StreamWriter streamWriter = new StreamWriter(path);

foreach(var line in stringList)
{
streamWriter.WriteLine(line);
}

streamWriter.Flush();
streamWriter.Close();
return stringList;
}

public static List<string> ToUpperTest(List<string> stringList)
{
List<string> upperList = new List<string>();

foreach(var line in stringList)
{
upperList.Add(line.ToUpper());
}

return upperList;
}

public static List<string> ToUpperInvariantTest(List<string> stringList)
{
List<string> upperList = new List<string>();

foreach (var line in stringList)
{
upperList.Add(line.ToUpperInvariant());
}

return upperList;
}

public static List<string> ToLowerTest(List<string> stringList)
{
List<string> lowerList = new List<string>();

foreach (var line in stringList)
{
lowerList.Add(line.ToLower());
}

return lowerList;
}

public static List<string> ToLowerInvariantTest(List<string> stringList)
{
List<string> lowerList = new List<string>();

foreach (var line in stringList)
{
lowerList.Add(line.ToLowerInvariant());
}

return lowerList;
}
}


}

3 Result

我使用了一个101850行, 容量为4.00 MB (4,202,730 bytes)的英文html文本进行测试。

测试环境:

  • CPU: Intel(R) Core(TM) i5-5300U CPU @ 2.30GHz 2.30GHz
  • RAM: 8.00GB (7.78 GB usable)
  • OS: Windows 7 Enterprise (Service Pack1) 64-bit

第1次:

1
2
3
4
5
6
7
8
line count: 101850
ReadString: 44ms
line count: 101850 ToUpperTest: 104ms
line count: 101850 ToUpperInvariantTest: 156ms
line count: 101850 ToLowerTest: 220ms
line count: 101850 ToLowerInvariantTest: 287ms
WriteStrings: 403ms
Press any key to continue . . .

第2次:

1
2
3
4
5
6
7
8
line count: 101850
ReadString: 36ms
line count: 101850 ToUpperTest: 91ms
line count: 101850 ToUpperInvariantTest: 139ms
line count: 101850 ToLowerTest: 197ms
line count: 101850 ToLowerInvariantTest: 262ms
WriteStrings: 368ms
Press any key to continue . . .

第3次

1
2
3
4
5
6
7
8
line count: 101850
ReadString: 29ms
line count: 101850 ToUpperTest: 79ms
line count: 101850 ToUpperInvariantTest: 125ms
line count: 101850 ToLowerTest: 179ms
line count: 101850 ToLowerInvariantTest: 237ms
WriteStrings: 339ms
Press any key to continue . . .

4 Conclusion

三次测试体现出,对于相同测试数据,性能上:

string.ToUpper > string.ToUpperInvariant > string.ToLower > string.ToLowerInvariant

即:

  • ToUpper转换快于ToLower转换。
  • Invariant转换在ToUpperToLower两种处理中,均增加了处理耗时。