将字符串中的第一个字符作为字符串获取的最快方法

时间:2013-11-26 12:02:05

标签: c# string performance

我需要获取字符串中的第一个字母,并尝试使用stringValue[0]。当我尝试将其作为参数传递给方法时,这会产生编译错误,因为该方法仅将string作为该参数的类型。所以我有几个选项可以将其转换为string

myMethod(stringValue[0].ToString());
myMethod(new String(stringValue[0], 1));
myMethod(stringValue.Substring(0,1));
myMethod("" + stringValue[0]);

哪种方法对性能最好,速度最快(也欢迎对最佳做法的想法)?

3 个答案:

答案 0 :(得分:2)

使用String.Substring

string firstChar = stringValue.Substring(0, 1);

根据你问题的表现部分。

  

除非确实如此,否则我不会考虑性能   实际上对你来说是个问题 - 在这种情况下,这是你唯一的方法   知道将有测试用例,然后很容易运行它们   每个选项的测试用例并比较结果。我期待   这里的子串可能是最快的,仅仅因为子串   总是最终从原始的一个块创建一个字符串   输入,而删除必须至少可能粘在一起   开始大块和结束大块。

Fastest way to remove first char in a string

但是,如果你想进行微优化并且你真的只需要第一个字符,那么字符串索引器+构造函数似乎比其他字符快一点:

string stringValue = "testtesttesttesttesttesttesttesttesttesttesttesttesttesttesttest";
var sw = new System.Diagnostics.Stopwatch();
string firstChar;
sw.Start();
for(int i=0; i<100000000; i++)
    firstChar = stringValue.Substring(0, 1);
sw.Stop();
Console.WriteLine("Substring Elapsed: " + sw.Elapsed);

sw.Restart();
for (int i = 0; i < 100000000; i++)
    firstChar = stringValue[0].ToString();
sw.Stop();
Console.WriteLine("Char[]-Indexer-ToString Elapsed: " + sw.Elapsed);

sw.Restart();
for (int i = 0; i < 100000000; i++)
    firstChar = new string(stringValue[0],1);
sw.Stop();
Console.WriteLine("Char[]-Indexer-Constructor Elapsed: " + sw.Elapsed);

结果:

Substring Elapsed: 00:00:03.0214131
Char[]-Indexer-ToString Elapsed: 00:00:02.1274226
Char[]-Indexer-Constructor Elapsed: 00:00:01.7042839

但请注意,这实际上是微观优化。在大多数情况下,可读性更为重要。还要考虑你可能需要在某个时间使用前两个字符,String.Substring很容易,数组索引器不能返回多个字符。

答案 1 :(得分:2)

提议的解决方案

string input = "This is a string";
string firstChar = new String(input[0], 1);

这是您可以执行的操作次数最少。

  1. 按索引
  2. 提取第一个char
  3. char传递给String
  4. 的构造函数

    String Constructor (Char, Int32)

    性能代码

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace StringPerf
    {
        class Program
        {
            static string firstChar;
    
            static void Main(string[] args)
            {
                string input = "This is a sample string";
                int count = 100000;
                RunPerf("Warmup", 1, () =>
                    {
                        PerfContructor(input);
                        PerfSubstring(input);
                        PerfAppend(input);
                    });
    
                Console.WriteLine();
                Console.WriteLine();
    
                RunPerf("Constructor", count, () => PerfContructor(input));
                Console.WriteLine();
    
                RunPerf("ToString", count, () => PerfToString(input));
                Console.WriteLine();
    
                RunPerf("Substring", count, () => PerfSubstring(input));
                Console.WriteLine();
    
                RunPerf("Append", count, () => PerfAppend(input));
    
                Console.ReadLine();
            }
    
            static void PerfContructor(string input)
            {
                firstChar = new String(input[0], 1);
            }
    
            static void PerfToString(string input)
            {
                firstChar = input[0].ToString();
            }
    
            static void PerfSubstring(string input)
            {
                firstChar = input.Substring(0, 1);
            }
    
            static void PerfAppend(string input)
            {
                firstChar = "" + input[0];
            }
    
            static void RunPerf(string name, int count, Action action)
            {
                var sw = new System.Diagnostics.Stopwatch();
                Console.WriteLine(string.Format("Starting perf for {0}. {1} times", name, count));
    
                sw.Start();
                for (int i = 0; i < count; i++)
                {
                    action();
                }
                sw.Stop();
                Console.WriteLine(string.Format("{0} completed in {1}", name, sw.Elapsed));
            }
        }
    }
    

    结果

    Starting perf for Warmup. 1 times
    Warmup completed in 00:00:00.0003153
    
    
    Starting perf for Constructor. 9999999 times
    Constructor completed in 00:00:00.1961569
    
    Starting perf for ToString. 9999999 times
    ToString completed in 00:00:00.2890530
    
    Starting perf for Substring. 9999999 times
    Substring completed in 00:00:00.2412256
    
    Starting perf for Append. 9999999 times
    Append completed in 00:00:00.3271857
    

答案 2 :(得分:0)

基于Tim SchmelterGusdor的答案,我自己做了一些测试,结果表明最快的方法是

stringValue[0].ToString()

new String(stringValue[0], 1)

两者中哪一个最快是不清楚的,因为我的测试对于这两个测试是不确定的。我尝试以不同的顺序运行它们,并且它改变了哪一个是最快的。

我跑了2E9次,这两种最快的方法花了大约30秒 相比之下,Substring方法为43秒,append方法为50秒。