我在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
答案 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的支持了解详情。
回到大约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上播放:():
ghc -O2
:约 0.72s Stringbuilder
版本已编译发布:围绕 0.87 非常接近 IMO
这里有99999:
所以不用担心它们似乎非常接近;)
但我并不感到惊讶 - 最后你所做的就是在控制台上打印一些东西 - 所以它应该只取决于你的操作系统/机器。
其他问题可能更有趣但我懒得为它们编写代码