功能语言很好,因为它们通过消除状态来避免错误,但也因为它们可以很容易地自动并行化,而不必担心线程数.
作为Win32开发人员,我可以将Haskell用于我的应用程序的一些dll吗?如果我这样做,是否会为我自动采取真正的优势?如果是这样,那么编译器给我这个优势呢?
F#是否并行自动编写多个内核和cpu的函数?你会看到任务管理器中的线程数增加吗?
基本上我的问题是,如何以实用的方式开始使用Haskell,如果我这样做,我真的会看到一些好处吗?
我喜欢F#; 我真的,真的.被"函数式编程"咬了之后,我强迫自己在有机会的时候使用它.事实上,我最近使用它(在一个星期的休假期间)来编写一个很好的AI算法.
但是,我尝试到目前为止(见与我第一次尝试一个SO问题在这里)似乎表明,虽然无疑是美丽的...... F#有我用过的所有语言中最慢的执行速度.
我在代码中做错了吗?
我在博客文章中详细解释了我的所作所为,在我的实验中,我看到OCaml和其他组的运行速度比F#快5到35倍.
我是唯一一个有这种经历的人吗?我觉得令人沮丧的是,我最喜欢的语言也是最慢的 - 有时到目前为止......
编辑:直接GitHub链接,代码以各种语言形式存在...
编辑2:感谢托马斯和丹尼尔,速度大大提高:
编辑3:Jon Harrop博士加入了战斗:60%的加速,使得ScoreBoard直接在"枚举"版本的数据上运行.现在,F#的命令版本运行速度比C++慢3-4倍,这对于基于VM的运行时来说是一个很好的结果.我认为问题解决了 - 谢谢你们!
EDIT4:在合并所有优化之后,这些就是结果(F#以命令式的方式达到C# - 现在,如果我只能做一些关于功能风格的话!)
微软是否有可能在虚拟机执行时制作F#程序,或者更有可能在编译时,检测程序是用函数式语言构建的,并自动更好地并行化?
现在我相信没有这样的努力来尝试执行一个程序,该程序作为单线程程序自动构建为多线程程序.
也就是说,开发人员会编写单线程程序.并且编译器会吐出一个多线程的编译程序,并在需要时使用互斥锁和同步.
这些优化是否会在进程线程计数中的任务管理器中可见,还是会低于该级别?
我正在解决项目Euler问题(在我学习C#之前做了23个第一个问题)而且我对我解决问题5的性能低下来感到困惑.
其内容如下:
2520是可以除以1到10中的每个数字而没有任何余数的最小数字.
可以被1到20的所有数字整除的最小正数是多少?
现在我的C#令人难以置信的原始蛮力解决方案在大约25秒内完成了这个问题.
var numbers = Enumerable.Range(1, 20);
int start = 1;
int result;
while (true)
{
if (numbers.All(n => start % n == 0))
{
result = start;
break;
}
start++;
}
Run Code Online (Sandbox Code Playgroud)
现在我的F#解决方案也使用暴力强制,但至少它会有更多的歧视,所以它"应该"在我的脑海中运行得更快,但它在约45秒时出现,所以它几乎是C#的两倍慢.
let p5BruteForce =
let divisors = List.toSeq ([3..20] |> List.rev)
let isDivOneToTwenty n =
let dividesBy =
divisors |> Seq.takeWhile(fun x -> n % x = 0)
Seq.length dividesBy = Seq.length divisors
let findNum n =
let rec loop n =
match isDivOneToTwenty n …
Run Code Online (Sandbox Code Playgroud) 我在F#中有一个lisp风格语言的翻译,刚刚进入优化阶段.对评估者的简单测试表明,我需要以极端的方式对其进行优化.但是,我没有F#性能或优化的一般背景知识.
F#程序优化是否有任何良好的常识资源?特别有用的是保持缓存一致性和令人惊讶的原始性能问题的技巧.粗略的搜索在互联网上没有透露太多.
谢谢!
我做了非常简单的C#和F#测试程序.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
namespace ConsoleApplication2
{
class Program
{
static int Remainder(int num)
{
return num % 2;
}
static int SumOfremainders(IEnumerable<int> list)
{
var sum = 0;
foreach (var num in list)
{
sum += Remainder(num);
}
return sum;
}
static void Main(string[] args)
{
Stopwatch sw = new Stopwatch();
var nums = Enumerable.Range(1, 10000000);
sw.Start();
var a = SumOfremainders(nums);
sw.Stop();
Console.WriteLine("Duration " + (sw.ElapsedMilliseconds));
Console.WriteLine("Sum of remainders: {0}", a);
}
}
} …
Run Code Online (Sandbox Code Playgroud) 与C#相比,有没有人知道F#在性能方面的衡量标准.我有一个带有大量矢量操作,光线碰撞算法等的C#光线跟踪器,并认为它们可能更容易用F#表示.我不是要问F#在表达数学问题上有多好,这里已经回答了这个问题,而是我应该期待更好或更差的表现?由于光线跟踪是非常高性能的,即使是性能不佳的小案例也可能是错误的地方.
编辑:
似乎已经有很多关于这个问题的问题我找不到了(如果你真的用"F#"这个词搜索任何东西都没有结果).这里有一个好处是以下答案:
F#提供了一些可以带来改变的与性能相关的功能.
首先,.NET上委托的实现目前效率很低,因此,F#使用自己的FastFunc类型来实现高性能的一流功能.
其次,F#使用.NET元数据来传递内联函数,以便可以跨API导出它们,当然,这可以在某些情况下显着提高性能.
最后,模式匹配在C#中表达非常费力,因为语言缺少模式匹配,但几乎不可能保持优化的C#代码等同于许多非平凡模式匹配.相反,F#编译器在编译期间积极优化模式匹配.
相反,C#编译器更擅长使用IEnumerables优化循环,并且更好地优化值类型的计算(例如复杂算术).
干杯,Jon Harrop.
当然,F#和C#都编译成IL而CLR JITter完成了大部分的工作,但是我想知道F#语言或其核心库中是否隐含了与C#相比性能较差的内容?
另外,在.net框架中使用函数式编程有什么东西可能会使它比C#慢吗?
我当然会坐下来测量差异,因为这确实是确定的唯一真正的方法,但我只是想知道是否有人对此话题有任何广泛的了解.
我知道这个问题的"销售推销"答案是肯定的,但技术上是否正确.
公共语言运行时(CLR)被设计为基于命令式编程(IP)的中间语言,但在处理声明性编程(DP)时这具有明显的含义.
那么,当在CLR中实现时,基于与Imperative Style不同的范式的语言效率如何?
我也觉得DP的步骤会产生一个额外的抽象层次,可能无法在所有表现形式进行建模,这是一个公平的评论吗?
我用F#做了一些简单的测试,看起来很棒,但是如果程序变得更复杂,我会错过一些东西吗?