是什么让这个F#在VS2012中变得如此之慢?

TBo*_*one 0 f# visual-studio

在Visual Studio 2012中,为什么此代码在交互模式下如此快速地执行,并且在作为控制台应用程序运行时如此缓慢?我有一台快速计算机,但在运行时功能完成之前我可以数到4,在交互式工作室窗口中甚至不能达到1.

令我烦恼的另一部分是,当我测试其他人的Project Euler#4的F#代码时,它们都运行良好.所以它让我相信这段代码有一些不是最优的.(它也很整洁干净>:P)

let reverse(digits:string) = 
     digits.ToCharArray() |> Array.rev |> System.String.Concat    

let isPalindrome(number:int) =        
    let text = number.ToString()
    if text.Length % 2 = 0 then                        
        text = reverse(text)        
    else
        false

let palindromes(floor:int, ceiling:int) =     
    seq {
        for i1 = floor to ceiling do
            for i2 = floor to ceiling do
                let result = i1 * i2
                if isPalindrome result then
                    yield result 
    }

let run = 
    palindromes(100, 999)    
    |> Seq.max
Run Code Online (Sandbox Code Playgroud)

摘要

为了后人,我将列出最有效的性能变化.

  • 删除Concat并改为创建新字符串.
  • 保留最大的回文而不是收集所有回文
  • 用计算反向替换反向的字符串版本

它仍然没有解释我的原始问题.但现在它可以忽略不计,很难说服自己花更多的时间在上面.我感谢大家的投入.谢谢!

pad*_*pad 6

如果在发布模式下编译项目(Optimize code打开选项),则几乎看不到运行程序和在F#Interactive中执行之间的区别.

如果您已阅读其他人的版本,则可以看到isPalindrome可以直接在数字上进行检查.但是,快速修复仍在使用String:

let reverse(digits:string) = 
     System.String (digits.ToCharArray() |> Array.rev)
Run Code Online (Sandbox Code Playgroud)

请注意,与String构造函数调用相比,字符串连接速度较慢.

正如@wsanville所说,奇数长度也可能是回文:

let isPalindrome(number:int) =        
    let text = number.ToString()
    text = reverse(text)  
Run Code Online (Sandbox Code Playgroud)

palindromes功能上,执行时间可以通过i2i1以下开始迭代来减少一半:

let palindromes(floor:int, ceiling:int) =     
    seq {
        for i1 = floor to ceiling do
            for i2 = i1 to ceiling do
                let result = i1 * i2
                if isPalindrome result then
                    yield result 
    }

let run = 
    palindromes(100, 999)    
    |> Seq.max
Run Code Online (Sandbox Code Playgroud)

通过这些简单的优化,您的代码在我的机器上运行速度提高了5倍.