为什么Toupper比Tolower快

  • 本文关键字:Tolower Toupper 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

让我们尝试 reproducing 结果

  // 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}");

跑步几次(变暖)我已经得到了结果(核心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

因此,您不能拒绝 ToLower的零假设与 ToUpper一样快,因此您的实验有错误::

  1. 您有不同的字符串来处理
  2. 处理简短(仅175字符)字符串仅一次(不在循环中)即时,因此错误可以enrous enourmous
  3. 您必须热身例行程序(为了编译要编译的方法,加载的组件,填充的caches等)

看来(经过的时间超过1秒,非常简单的操作)是规则#3(热身)破坏了实验

您对ToUpper的Intial假设比ToLower快具有逻辑谬误。

您的转化为文化敏感。您没有执行顺序操作,而是执行取决于当前文化的操作(如CultureInfo.CurrentCulture返回)。在您使用的文化中,从下部情况到上案的转换可能会更快,并且它可能会在另一个文化中慢。一种文化中的转化也可能比另一种文化中的转换更快。

因此,您最初的假设是 ToUpperToLower的一个性能。

最新更新