我在 codeeval 上做了一些挑战,当我看到结果时我感到很震惊。 Haskell 结果往往比 C# 解决方案快几倍。我知道这两种语言是不同的,但任何人都可以向我解释(尽可能简单)为什么差异如此之大?是 haskell 的优越性还是 codeeval 的错误?
一些例子: 挑战:奇数,时间(毫秒):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 -> 2,C# -> 166
挑战:数字求和,时间:haskell -> 1, C# -> 168
挑战:交换数字,时间:haskell -> 7,C# -> 355
最佳答案
对于 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 风格
回到大约 10 毫秒但更接近 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
的原始 Haskell 版本:大约 0.72s - 我上面发布的
Stringbuilder
版本编译发布:0.87
非常接近 IMO
这里有 99999:
- C# 8.2s
- haskell :8.2s
所以不用担心,它们看起来非常接近 ;)
但我一点也不感到惊讶 - 最后你所做的就是向控制台打印一些东西 - 所以它应该只取决于你的操作系统/机器。
其他问题可能更有趣,但我懒得写代码了
关于c# - haskell 处理速度比 C# (codeeval) 快得多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31160546/