haskell处理比C#(codeeval)快得多

时间:2015-07-01 11:53:49

标签: c# haskell

我在codeeval上做了一些挑战,当我看到结果时我感到很震惊。 Haskell结果往往比C#解决方案快几倍。我知道两种语言都不一样,但任何人都可以向我解释(尽可能简单)为什么差异如此之大?它具有优势还是仅仅是代码错误?

一些例子: 挑战:奇数,时间(ms):haskell - > 1,C# - > 123

C#     使用系统;     使用System.IO;

class Program
{
    static void Main(string[] args)
    {
         for(int i=1;i<=99;i++)
            {
            if(i%2==1) Console.WriteLine(i);
            }
    }
}

的Haskell

main = do
    putStrLn $ init . drop 1 . replace ',' '\n' . show . filter odd $ [1..99]


replace :: Char -> Char -> String -> String
replace c1 c2 line = map (\letter -> if letter==c1 then c2 else letter) line

挑战:反向词,时间:haskell - &gt; 2,C# - &gt; 166

挑战:数字之和,时间:haskell - &gt; 1,C# - &gt; 168

挑战:交换号码,时间:haskell - &gt; 7,C# - &gt; 355

1 个答案:

答案 0 :(得分:7)

对于C#,它是您的Console.WriteLine

这一个:

    var timer = new Stopwatch();
    timer.Start();
    var sb = new StringBuilder();
    for (int i = 1; i <= 99; i++)
    {
        if (i%2 == 1) sb.AppendLine(i.ToString());
    }
    Console.Write(sb.ToString());
    timer.Stop();
    Console.WriteLine("took {0:0.0}ms", timer.Elapsed.TotalMilliseconds);

在我的机器上发布时需要1-2毫秒,你需要大约10毫秒

对于他们的网站,可能需要更长时间,具体取决于他们对输出的处理方式。

除此之外,C#生成的代码仍将被某些运行时解释,因此您甚至可以测量初始化/启动

Haskell可能不会(尽管他们可能只是runhaskell ......(?))

我想你必须要求CodeEval的支持了解详情。

LINQ风格

回到大约10ms但更接近Haskell

    var numbers =
        String.Join("\n",
        Enumerable
            .Range(1, 99)
            .Where(i => i%2 == 1)
            .Select(i => i.ToString()));

    Console.WriteLine(numbers);

一些有趣/性能测试

我在 eshell time ./prg.exe中将范围扩展为9999(是的,我现在正在Windows上播放:():

  • 原始Haskell版本ghc -O2:约 0.72s
  • 我上面发布的Stringbuilder版本已编译发布:围绕 0.87

非常接近 IMO

这里有99999:

  • C# 8.2s
  • Haskell: 8.2s

所以不用担心它们似乎非常接近;)

但我并不感到惊讶 - 最后你所做的就是在控制台上打印一些东西 - 所以它应该只取决于你的操作系统/机器。

其他问题可能更有趣但我懒得为它们编写代码