高效的String分割类
smark http://www.ikende.com/
Beetle可靠、高性能的.Net Socket Tcp通讯组件 支持flash amf3,protobuf,Silverlight,windows phone
分享一个高效的String分割类
最近在制定一个网络文件交互的协议,协议制订上采用了HTTP协议的方式,因此需对协议数据进行一个分割处理;虽然使用String的Split方法可以达到目的,但通过反编译查看其代码后发现实现相对复杂,性能上也不怎样;于是自己实现一个简单的字符分割处理类,在实现后和String的Sqlit方法进行了一个简单的对比,发现性能要比Sqlit高所以分享出来.
测试情况
分割处理的内容Content-Encoding:gzip
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
Set-Cookie:smark=Branch=default&IsProject=1; domain=.codeplex.com; expires=Fri, 31-Oct-2042 14:17:06 GMT; path=/
Vary:Accept-Encoding
X-Powered-By:ASP.NET
测试分两部分,先是按/r/n进行的分割后,再进行属性侵害,具体测试代码如下:
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" , ':' );
}
}
为了保证测试在跑之前都进行了预热运行
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高效出一倍,在处理了两次分割效率依然没有多少的损失.
完整代码
using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
namespace Smark
{
/// <summary>
/// Copyright ? henryfan 2012
/// Email: henryfan@msn.com
/// 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);
}
}
}
作者: Leo_wl
出处: http://www.cnblogs.com/Leo_wl/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
版权信息