分享一个高效的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进行的分割后,再进行属性侵害,具体测试代码如下:
        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:	[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);

        }

    }

}

 

你可能感兴趣的:(String)