高效的String分割类

分享一个高效的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);
         }
     }
}

 

专注于可靠、高性能的Socket TCP通讯组件
c#组件设计交流群:47164588 
c# socket :285021077

你可能感兴趣的:(String)