字符串ctor是转换IEnumerable< char>的最快方法吗?串 [英] Is the string ctor the fastest way to convert an IEnumerable<char> to string

查看:113
本文介绍了字符串ctor是转换IEnumerable< char>的最快方法吗?串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为.Net Core 2.1发行版进行了编辑

重复测试.Net Core 2.1发行版的过程,我得到了这样的结果

Repeating the test for the release of .Net Core 2.1, I get results like this


1000000次 Concat迭代

1000000 iterations of "Concat" took 842ms.

new String的1000000次迭代;耗时842ms。

1000000 iterations of "new String" took 1009ms.

1000000次 sb迭代耗时100ms。花费了902毫秒。

1000000 iterations of "sb" took 902ms.

简而言之,如果您使用的是.Net Core 2.1或更高版本,则 Concat

In short, if you are using .Net Core 2.1 or later, Concat is king.

我已经编辑问题,以将有效的观点纳入评论中。

I've edited the question to incorporate the valid points raised in the comments.

我一直在沉思我对上一个问题的回答,我开始想知道这是

I was musing on my answer to a previous question and I started to wonder, is this,

return new string(charSequence.ToArray());

IEnumerable< char> 转换为字符串。我做了一下搜索,发现这个问题已经在这里问过。该答案断言,

The best way to convert an IEnumerable<char> to a string. I did a little search and found this question already asked here. That answer asserts that,

string.Concat(charSequence)

是更好的选择。在回答了这个问题之后,还提出了 StringBuilder 枚举方法,

is a better choice. Following an answer to this question, a StringBuilder enumeration approach was also suggested,

var sb = new StringBuilder();
foreach (var c in chars)
{
    sb.Append(c);
}

return sb.ToString();

虽然这可能有点笨拙,但出于完整性考虑,我将其包括在内。我决定应该做一点测试,所用的代码在底部。

while this may be a little unwieldy I include it for completeness. I decided I should do a little test, the code used is at the bottom.

在发布模式下进行优化时,在不附加调试器的情况下从命令行运行时,我得到结果

When built in release mode, with optimizations, and run from the command line without the debugger attached I get results like this.


1000000次 Concat迭代

1000000 iterations of "Concat" took 1597ms.

新字符串的1000000次迭代耗时1597毫秒。

1000000 iterations of "new String" took 869ms.

1000000次 sb迭代耗时869ms。花了748毫秒。

1000000 iterations of "sb" took 748ms.

据我估计,新字符串(... ToArray()) string.Concat 方法的两倍。 StringBuilder 仍然略快一些,但使用起来很尴尬,但可能是扩展。

To my reckoning, the new string(...ToArray()) is close to twice as fast as the string.Concat method. The StringBuilder is marginally faster still but, is awkward to use but could be an extension.

我应该坚持使用 new string(... ToArray())还是我缺少什么?

Should I stick with new string(...ToArray()) or, is there something I'm missing?

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;

class Program
{
    private static void Main()
    {
        const int iterations = 1000000;
        const string testData = "Some reasonably small test data";

        TestFunc(
            chars => new string(chars.ToArray()),
            TrueEnumerable(testData),
            10,
            "new String");

        TestFunc(
            string.Concat,
            TrueEnumerable(testData),
            10,
            "Concat");

        TestFunc(
            chars =>
            {
                var sb = new StringBuilder();
                foreach (var c in chars)
                {
                    sb.Append(c);
                }

                return sb.ToString();
            },
            TrueEnumerable(testData),
            10,
            "sb");

        Console.WriteLine("----------------------------------------");

        TestFunc(
            string.Concat,
            TrueEnumerable(testData),
            iterations,
            "Concat");

        TestFunc(
            chars => new string(chars.ToArray()),
            TrueEnumerable(testData),
            iterations,
            "new String");

        TestFunc(
            chars =>
            {
                var sb = new StringBuilder();
                foreach (var c in chars)
                {
                    sb.Append(c);
                }

                return sb.ToString();
            },
            TrueEnumerable(testData),
            iterations,
            "sb");

        Console.ReadKey();
    }

    private static TResult TestFunc<TData, TResult>(
            Func<TData, TResult> func,
            TData testData,
            int iterations,
            string stage)
    {
        var dummyResult = default(TResult);

        var stopwatch = Stopwatch.StartNew();
        for (var i = 0; i < iterations; i++)
        {
            dummyResult = func(testData);
        }

        stopwatch.Stop();
        Console.WriteLine(
            "{0} iterations of \"{2}\" took {1}ms.",
            iterations,
            stopwatch.ElapsedMilliseconds,
            stage);

        return dummyResult;
    }

    private static IEnumerable<T> TrueEnumerable<T>(IEnumerable<T> sequence)
    {
        foreach (var t in sequence)
        {
            yield return t;
        }
    }
}


推荐答案

值得注意的是,尽管从纯粹主义者的角度来看,对于IEnumerable而言确实如此,但并非总是如此。例如,即使您实际上将一个char数组作为IEnumerable传递给它,调用字符串构造函数也更快。

It's worth noting that these results, whilst true for the case of IEnumerable from a purists point of view, are not always thus. For example if you were to actually have a char array even if you are passed it as an IEnumerable it is faster to call the string constructor.

结果:

Sending String as IEnumerable<char> 
10000 iterations of "new string" took 157ms. 
10000 iterations of "sb inline" took 150ms. 
10000 iterations of "string.Concat" took 237ms.
======================================== 
Sending char[] as IEnumerable<char> 
10000 iterations of "new string" took 10ms.
10000 iterations of "sb inline" took 168ms.
10000 iterations of "string.Concat" took 273ms.

代码:

static void Main(string[] args)
{
    TestCreation(10000, 1000);
    Console.ReadLine();
}

private static void TestCreation(int iterations, int length)
{
    char[] chars = GetChars(length).ToArray();
    string str = new string(chars);
    Console.WriteLine("Sending String as IEnumerable<char>");
    TestCreateMethod(str, iterations);
    Console.WriteLine("===========================================================");
    Console.WriteLine("Sending char[] as IEnumerable<char>");
    TestCreateMethod(chars, iterations);
    Console.ReadKey();
}

private static void TestCreateMethod(IEnumerable<char> testData, int iterations)
{
    TestFunc(chars => new string(chars.ToArray()), testData, iterations, "new string");
    TestFunc(chars =>
    {
        var sb = new StringBuilder();
        foreach (var c in chars)
        {
            sb.Append(c);
        }
        return sb.ToString();
    }, testData, iterations, "sb inline");
    TestFunc(string.Concat, testData, iterations, "string.Concat");
}

这篇关于字符串ctor是转换IEnumerable&lt; char&gt;的最快方法吗?串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆