分享一个高效的String分割类
最近在制定一个网络文件交互的协议,协议制订上采用了HTTP协议的方式,因此需对协议数据进行一个分割处理;虽然使用String的Split方法可以达到目的,但通过反编译查看其代码后发现实现相对复杂,性能上也不怎样;于是自己实现一个简单的字符分割处理类,在实现后和String的Sqlit方法进行了一个简单的对比,发现性能要比Sqlit高所以分享出来.
测试情况
- 分割处理的内容
Cache-Control:public, max-age=0
Content-Encoding:gzip
Content-Length:9480
Content-Type:text/html; charset=utf-8
Date:Wed, 31 Oct 2012 14:17:06 GMT
Expires:Wed, 31 Oct 2012 14:17:05 GMT
Last-Modified:Wed, 31 Oct 2012 14:17:05 GMT
P3P:CP=NON DSP COR ADM CUR DEV TAI OUR IND NAV PRE STA
P3P:CP=NON DSP COR ADM CUR DEV TAI OUR IND NAV PRE STA
Server:Microsoft-IIS/7.5
Set-Cookie:smark=Branch=default&IsProject=1; domain=.codeplex.com; expires=Fri, 31-Oct-2042 14:17:06 GMT; path=/
Vary:Accept-Encoding
X-AspNet-Version:4.0.30319
X-AspNetMvc-Version:4.0
X-Powered-By:ASP.NET
- 测试分两部分,先是按/r/n进行的分割后,再进行属性侵害,具体测试代码如下:
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
|
static
void
StringSplit(
string
value)
{
for
(
int
i = 0; i < count; i++)
{
value.Split(
new
string
[] {
"\r\n\r\n"
}, StringSplitOptions.RemoveEmptyEntries);
}
}
static
void
StringExtendSplit(
string
value)
{
for
(
int
i = 0; i < count; i++)
{
Smark.StringExtend.Split(value,
"\r\n\r\n"
);
}
}
static
void
StringToProperties(
string
value)
{
for
(
int
i = 0; i < count; i++)
{
System.Collections.Hashtable properties =
new
System.Collections.Hashtable(8);
string
[] lines = value.Split(
new
string
[] {
"\r\n"
}, StringSplitOptions.RemoveEmptyEntries);
int
spindex;
string
pvalue;
for
(
int
k = 0; k < lines.Length; k++)
{
pvalue = lines[k];
spindex = pvalue.IndexOf(
':'
);
properties[pvalue.Substring(0, spindex)] = pvalue.Substring(spindex + 1, pvalue.Length- spindex-1);
}
}
}
static
void
StringExtendToProperties(
string
value)
{
for
(
int
i = 0; i < count; i++)
{
System.Collections.Hashtable properties= Smark.StringExtend.GetProperties(value,
"\r\n\r\n"
,
':'
);
}
}
|
- 为了保证测试在跑之前都进行了预热运行
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
|
StringSplit(value);
StringExtendSplit(value);
StringExtendToProperties(value);
StringToProperties(value);
System.Diagnostics.Stopwatch sw =
new
System.Diagnostics.Stopwatch();
sw.Reset();
sw.Start();
StringSplit(value);
sw.Stop();
Console.WriteLine(
"StringSplit:{0}ms"
, sw.Elapsed.TotalMilliseconds);
sw.Reset();
sw.Start();
StringExtendSplit(value);
sw.Stop();
Console.WriteLine(
"StringExtendSplit:{0}ms"
, sw.Elapsed.TotalMilliseconds);
sw.Reset();
sw.Start();
StringToProperties(value);
sw.Stop();
Console.WriteLine(
"StringToProperties:{0}ms"
, sw.Elapsed.TotalMilliseconds);
sw.Reset();
sw.Start();
StringExtendToProperties(value);
sw.Stop();
Console.WriteLine(
"StringExtendToProperties:{0}ms"
, sw.Elapsed.TotalMilliseconds);
|
- 10000次的处理结果
Release 执行Exe的测试结果来看单是Split方法就比String.Split方法高出一倍的性能.即使是进一步属性的分割也比一个String.Split高效出一倍,在处理了两次分割效率依然没有多少的损失.
- 完整代码
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
|
using
System;
using
System.Collections.Generic;
using
System.Collections;
using
System.Text;
namespace
Smark
{
/// <summary>
/// Copyright © henryfan 2012
/// Email: [email protected]
/// HomePage: http://www.ikende.com
/// CreateTime: 2012/11/1 21:36:19
/// </summary>
public
class
StringExtend
{
public
static
int
DefaultResultLength = 8;
public
static
IList<
string
> Split(
byte
[] data, Encoding coding,
int
start,
int
count,
string
splitdata)
{
return
Split(coding.GetString(data, start, count), splitdata);
}
public
static
IList<
string
> Split(
string
value,
string
splitdata)
{
List<
string
> result =
new
List<
string
>(DefaultResultLength);
int
startIndex = 0;
bool
eq =
false
;
int
sindex = 0;
int
splitlength = splitdata.Length;
int
datalength = value.Length;
while
(sindex < value.Length)
{
eq =
true
;
for
(
int
k = 0; k < splitlength; k++)
{
if
(value[sindex + k] != splitdata[k])
{
eq =
false
;
break
;
}
}
if
(eq)
{
sindex += splitlength;
if
(sindex - splitlength > startIndex)
result.Add(value.Substring(startIndex, sindex - startIndex - splitlength));
startIndex = sindex;
}
else
{
sindex++;
}
}
if
(startIndex < datalength)
{
if
(sindex - splitlength > startIndex)
result.Add(value.Substring(startIndex, datalength - startIndex));
}
return
result;
}
public
static
Hashtable GetProperties(
string
value,
string
linesplit,
char
propertysplit)
{
Hashtable result =
new
Hashtable(DefaultResultLength);
int
splitlength = linesplit.Length;
int
startIndex = 0;
bool
eq =
false
;
int
sindex = 0;
int
propertyindex = 0;
while
(sindex < value.Length)
{
eq =
true
;
if
(propertyindex == 0 && value[sindex] == propertysplit)
propertyindex = sindex;
for
(
int
k = 0; k < splitlength; k++)
{
if
(value[sindex + k] != linesplit[k])
{
eq =
false
;
break
;
}
}
if
(eq)
{
if
(sindex > startIndex)
{
result[value.Substring(startIndex, propertyindex - startIndex)] = value.Substring(propertyindex + 1, sindex - propertyindex);
}
sindex += splitlength;
propertyindex = 0;
startIndex = sindex;
}
else
{
sindex++;
}
}
if
(startIndex < value.Length)
{
result[value.Substring(startIndex, propertyindex - startIndex)] = value.Substring(propertyindex + 1, sindex - propertyindex);
}
return
result;
}
public
static
Hashtable GetProperties(
byte
[] data, Encoding coding,
int
start,
int
count,
string
linesplit,
char
propertysplit)
{
return
GetProperties(coding.GetString(data, start, count), linesplit, propertysplit);
}
}
}
|
c#组件设计交流群:47164588
c# socket :285021077