当然,F#和C#都编译为IL,而CLR JITter完成了大部分的努力工作,但是我想知道F#语言或其核心库中是否有隐含的内容导致与C#相比性能较低?与C#相比,F#的性能如何?
另外,在.net框架中使用函数式编程有没有什么可能使它比C#慢呢?
我打算坐下来,尺寸当然不同,因为这确实是唯一真正知道的方法,但我只是想知道是否有人对这个主题有广泛的知识。
此外当然,F#和C#都编译为IL,而CLR JITter完成了大部分的努力工作,但是我想知道F#语言或其核心库中是否有隐含的内容导致与C#相比性能较低?与C#相比,F#的性能如何?
另外,在.net框架中使用函数式编程有没有什么可能使它比C#慢呢?
我打算坐下来,尺寸当然不同,因为这确实是唯一真正知道的方法,但我只是想知道是否有人对这个主题有广泛的知识。
此外见一个很好的例子是埃拉托塞尼的筛。
一位同事,我用C#和F#编写了类似的筛子。 C#版本的性能比我的同事编写的功能性版本慢了近10倍。
C#版本中可能有些效率低下的问题可能已经清理完毕,但F#版本明显更快。
这种问题适合于被写在函数式语言..
希望这有助于一些。
编辑 -
下面是使用类似的功能,以F#的List.Partition C#的例子之一。我将继续寻找F#示例。我有数以百计的项目,它可能是,它只是通过我的所有的东西找到它排序的事情(我保存所有我曾经尝试着,所以这可能是费时..笑)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ListPartitionTest
{
public static class IEnumerableExtensions
{
public static KeyValuePair<IEnumerable<T>, IEnumerable<T>> Partition<T>(this IEnumerable<T> items, Func<T, bool> f)
{
return items.Aggregate(
new KeyValuePair<IEnumerable<T>, IEnumerable<T>>(Enumerable.Empty<T>(), Enumerable.Empty<T>()),
(acc, i) =>
{
if (f(i))
{
return new KeyValuePair<IEnumerable<T>, IEnumerable<T>>(acc.Key.Concat(new[] { i }), acc.Value);
}
else
{
return new KeyValuePair<IEnumerable<T>, IEnumerable<T>>(acc.Key, acc.Value.Concat(new[] { i }));
}
});
}
}
class PrimeNumbers
{
public int Floor { get; private set; }
public int Ceiling { get; private set; }
private IEnumerable<int> _sieve;
public PrimeNumbers(int floor, int ceiling)
{
Floor = floor;
Ceiling = ceiling;
}
public List<int> Go()
{
_sieve = Enumerable.Range(Floor, (Ceiling - Floor) + 1).ToList();
for (int i = (Floor < 2) ? 2 : Floor; i <= Math.Sqrt(Ceiling); i++)
{
_sieve = _sieve.Where(x => (x % i != 0 && x != i));
foreach (int x in _sieve)
{
Console.Write("{0}, ", x);
}
Console.WriteLine();
}
return _sieve.ToList();
}
}
class Program
{
static void Main(string[] args)
{
System.Diagnostics.Stopwatch s = new System.Diagnostics.Stopwatch();
int floor = 1;
int ceiling = 10;
s.Start();
PrimeNumbers p = new PrimeNumbers(floor, ceiling);
p.Go();
//foreach (int i in p.Go()) Console.Write("{0} ", i);
s.Stop();
Console.WriteLine("\n{0} to {1} completed in {2}", floor, ceiling, s.Elapsed.TotalMilliseconds);
Console.ReadLine();
}
}
}
没有什么内在的东西让一种语言比另一种语言更快。它们都运行在CLR上,因此与运行在CLR上的任何语言具有大致相同的性能特征。尽管这会影响性能,但各种语言还是有其特点的。
尾递归是一个很好的例子。如果您编写了一个大量使用尾递归的F#应用程序,编译器会尝试将其重写为迭代循环,消除了递归惩罚。此外,F#使用.tail IL操作码来请求CLR在可能的情况下删除递归堆栈罚款。
通过将一些F#延续样本转换为C#然后插入巨大的数据集很容易证明这一点。 F#将起作用,C#最终会崩溃。
但不一定是在C#中的缺陷。 C#并不意味着用延续书写,而在F#中肯定是这样。事实上,在C#中为F#编写算法产生的结果并不那么理想。
相反,C#迭代器通常比F#序列表达式更高效。原因是C#迭代器是非常高效的状态机,而F#则是延续传递。
一般来说,虽然在线程的缺失情况下,如果您使用的语言是打算使用的,它们将具有相似的性能特征。
同一问题在这里:http://stackoverflow.com/questions/144227/cf-performance-comparison – splattne 2009-01-24 14:30:09
和这里:http://stackoverflow.com/questions/142985/is-a-program-f-any-更有效的执行方式比c更容易 – splattne 2009-01-24 14:32:22
只是把它扔到那里,但是重复的东西应该被编辑到IMO的原始文章中。使答案更容易找到答案,因为重复和类似问题的链接就在那里,清晰可见。 – 2009-01-24 14:58:25