焦炭>到转换IEnumerable的&LT的最佳方式;串?焦炭、方式、IEnumerable、gt

2023-09-03 04:43:56 作者:煮酒燃烟

为什么不能够使用流利的语言对字符串

例如:

  VAR X =asdf1234;
变种Y =新的字符串(x.TakeWhile(char.IsLetter).ToArray());
 

难道没有更好的办法来转换的IEnumerable<焦炭> 字符串

搜狐文化 搜狐网

下面是测试我所做的:

 类节目
{
  静态字符串输入=asdf1234;
  静态无效的主要()
  {
    Console.WriteLine(1000次:);
    的runTest(1000,输入);
    Console.WriteLine(10000次:);
    的runTest(10000,输入);
    Console.WriteLine(10万次:);
    的runTest(100000,输入);
    Console.WriteLine(10万次:);
    的runTest(100000,ffff57467);


    Console.ReadKey();

  }

  静态无效的runTest(INT次,串输入)
  {

    秒表SW =新的秒表();

    sw.Start();
    的for(int i = 0; I<次;我++)
    {
      字符串输出=新的字符串(input.TakeWhile(char.IsLetter).ToArray());
    }
    sw.Stop();
    VAR第一= sw.ElapsedTicks;

    sw.Restart();
    的for(int i = 0; I<次;我++)
    {
      字符串输出= Regex.Match(输入,@^ [A-Z] +,
        RegexOptions.IgnoreCase).value的;
    }
    sw.Stop();
    VAR秒= sw.ElapsedTicks;

    VAR正则表达式=新的正则表达式(@^ [A-Z] +,
      RegexOptions.IgnoreCase);
    sw.Restart();
    的for(int i = 0; I<次;我++)
    {
      无功输出= regex.Match(输入).value的;
    }
    sw.Stop();
    VAR第三= sw.ElapsedTicks;

    双百分比=(第一+第二+三)/ 100;
    双P1 =(第一/百分比)/ 100;
    双P2 =(秒/百分比)/ 100;
    双P3 =(第三/百分比)/ 100;


    Console.WriteLine(TakeWhile了{0}({1:P2})。,第一,P1);
    Console.WriteLine(正则表达式了{0},({1:P 2})。,第二,P2);
    Console.WriteLine(pinstantiated正则表达式$ P $拿着{0},({1:P2}),第三次,第3页);
    Console.WriteLine();
  }
}
 

结果:

  1000次:
TakeWhile了11217(62.32%)。,
正则表达式了5044,(28.02%)。
pinstantiated正则表达式$ P $ 1741了,(9.67%)。

10000次:
TakeWhile了9210(14.78%),
正则表达式了32461,(52.10%)。
pinstantiated正则表达式$ P $拿了20669,(33.18%)。

100000次:
TakeWhile了74945条(13.10%),
正则表达式了324520(56.70%)。
pinstantiated正则表达式$ P $拿了172913(30.21%)。

100000次:
TakeWhile了74511(13.77%),
正则表达式了297760(55.03%)。
pinstantiated正则表达式$ P $拿了168911(31.22%)。
 

结论:我怀疑什么是更好的preFER,我想我会去的 TakeWhile 这是最慢的只在第一次运行

不管怎样,我的问题是,如果有任何方式restringing的 TakeWhile 函数的结果来优化性能。

解决方案

假设你正在寻找predominantly的表现,那么这样的事情应该是大大快于你的任何例子:

 字符串x =asdf1234;
字符串Y = x.LeadingLettersOnly();

// ...

公共静态类StringExtensions
{
    公共静态字符串LeadingLettersOnly(此字符串源)
    {
        如果(来源== NULL)
            抛出新ArgumentNullException(源);

        如果(source.Length == 0)
            返回源;

        的char []缓冲区=新的char [source.Length]
        INT bufferIndex = 0;

        对于(INT sourceIndex = 0; sourceIndex< source.Length; sourceIndex ++)
        {
            焦炭C =源[sourceIndex]

            如果(!char.IsLetter(c))的
                打破;

            缓冲[bufferIndex ++] = C;
        }
        返回新的字符串(缓冲,0,bufferIndex);
    }
}
 

Why isn't it possible to use fluent language on string?

For example:

var x = "asdf1234";
var y = new string(x.TakeWhile(char.IsLetter).ToArray());

Isn't there a better way to convert IEnumerable<char> to string?

Here is a test I've made:

class Program
{
  static string input = "asdf1234";
  static void Main()
  {
    Console.WriteLine("1000 times:");
    RunTest(1000, input);
    Console.WriteLine("10000 times:");
    RunTest(10000,input);
    Console.WriteLine("100000 times:");
    RunTest(100000, input);
    Console.WriteLine("100000 times:");
    RunTest(100000, "ffff57467");


    Console.ReadKey();

  }

  static void RunTest( int times, string input)
  {

    Stopwatch sw = new Stopwatch();

    sw.Start();
    for (int i = 0; i < times; i++)
    {
      string output = new string(input.TakeWhile(char.IsLetter).ToArray());
    }
    sw.Stop();
    var first = sw.ElapsedTicks;

    sw.Restart();
    for (int i = 0; i < times; i++)
    {
      string output = Regex.Match(input, @"^[A-Z]+", 
        RegexOptions.IgnoreCase).Value;
    }
    sw.Stop();
    var second = sw.ElapsedTicks;

    var regex = new Regex(@"^[A-Z]+", 
      RegexOptions.IgnoreCase);
    sw.Restart();
    for (int i = 0; i < times; i++)
    {
      var output = regex.Match(input).Value;
    }
    sw.Stop();
    var third = sw.ElapsedTicks;

    double percent = (first + second + third) / 100;
    double p1 = ( first / percent)/  100;
    double p2 = (second / percent )/100;
    double p3 = (third / percent  )/100;


    Console.WriteLine("TakeWhile took {0} ({1:P2}).,", first, p1);
    Console.WriteLine("Regex took {0}, ({1:P2})." , second,p2);
    Console.WriteLine("Preinstantiated Regex took {0}, ({1:P2}).", third,p3);
    Console.WriteLine();
  }
}

Result:

1000 times:
TakeWhile took 11217 (62.32%).,
Regex took 5044, (28.02%).
Preinstantiated Regex took 1741, (9.67%).

10000 times:
TakeWhile took 9210 (14.78%).,
Regex took 32461, (52.10%).
Preinstantiated Regex took 20669, (33.18%).

100000 times:
TakeWhile took 74945 (13.10%).,
Regex took 324520, (56.70%).
Preinstantiated Regex took 172913, (30.21%).

100000 times:
TakeWhile took 74511 (13.77%).,
Regex took 297760, (55.03%).
Preinstantiated Regex took 168911, (31.22%).

Conclusion: I'm doubting what's better to prefer, I think I'm gonna go on the TakeWhile which is the slowest only on first run.

Anyway, my question is if there is any way to optimize the performance by restringing the result of the TakeWhile function.

解决方案

Assuming that you're looking predominantly for performance, then something like this should be substantially faster than any of your examples:

string x = "asdf1234";
string y = x.LeadingLettersOnly();

// ...

public static class StringExtensions
{
    public static string LeadingLettersOnly(this string source)
    {
        if (source == null)
            throw new ArgumentNullException("source");

        if (source.Length == 0)
            return source;

        char[] buffer = new char[source.Length];
        int bufferIndex = 0;

        for (int sourceIndex = 0; sourceIndex < source.Length; sourceIndex++)
        {
            char c = source[sourceIndex];

            if (!char.IsLetter(c))
                break;

            buffer[bufferIndex++] = c;
        }
        return new string(buffer, 0, bufferIndex);
    }
}

 
精彩推荐
图片推荐