为什么ToUpper比ToLower快?

时间:2016-12-20 08:52:45

标签: c# .net

Stopwatch stopwatch1 = new Stopwatch();
Stopwatch stopwatch2 = new Stopwatch();
string l = "my test";
string u = "MY TEST";

for (int i = 0; i < 25; i++)
{
    l += l;
    u += u;
}

stopwatch1.Start();
l=l.ToUpper();
stopwatch1.Stop();

stopwatch2.Start();
u=u.ToLower();
stopwatch2.Stop();

// Write result.
Console.WriteLine("Time elapsed: \nUPPER :  {0}\n LOWER : {1}",
                  stopwatch1.Elapsed, stopwatch2.Elapsed);

我跑过很多次了:

UPPER : 00:00:01.3386287
LOWER : 00:00:01.4546552

UPPER : 00:00:01.1614189
LOWER : 00:00:01.1970368

UPPER : 00:00:01.2697430
LOWER : 00:00:01.3460950

UPPER : 00:00:01.2256813
LOWER : 00:00:01.3075738

2 个答案:

答案 0 :(得分:6)

让我们尝试再现结果

  // Please, notice: the same string for both ToUpper/ToLower
  string GiniPig = string.Concat(Enumerable
    .Range(1, 1000000) // a million chunks "my test/MyTest" combined (long string)
    .Select(item => "my test/MY TEST"));

   Stopwatch sw = new Stopwatch();

   // Let's try n (100) times - not just once
   int n = 100;

   var sampling = Enumerable
     .Range(1, n)
     .Select(x => {
        sw.Reset();
        sw.Start();

        GiniPig.ToLower(); // change this into .ToUpper();

        sw.Stop();
        return sw.ElapsedMilliseconds; })
     .ToSampling(x => x); // Side library; by you may save the data and analyze it with R

   Console.Write(
     $"N = {n}; mean = {sampling.Mean:F0}; std err = {sampling.StandardDeviation:F0}");

跑了几次(变暖)我得到了结果(Core i7 3.6 GHz,.Net 4.6 IA-64):

ToLower: N = 100; mean = 38; std err = 8
ToUpper: N = 100; mean = 37; std err = 9

因此,您无法拒绝 ToLowerToUpper一样快的原假设,因此您的实验已经错误

  1. 您要处理不同的字符串
  2. 处理(仅限175个字符)字符串只需一次(不在循环中)应该是即时的,因此错误可能很有意义
  3. 你必须预热例程(按顺序编译方法,加载程序集,填充缓存等)。
  4. 似乎(经过的时间超过1秒,非常容易操作)它的规则#3(预热)破坏破坏了实验

答案 1 :(得分:3)

ToUpperToLower更快的初始假设具有逻辑谬误。

您的转化文化敏感。您没有执行序数操作,您正在执行取决于您当前文化的操作(由CultureInfo.CurrentCulture返回)。从小写到大写的转换可能在您正在使用的文化中更快,并且可能在另一个文档中更慢。一种文化中的转换可能也比另一种文化中的转换更快。

因此,您对ToUpperToLower一个效果的初步假设是错误的。