Performance Dart中功能风格的性能增益

Performance Dart中功能风格的性能增益,performance,functional-programming,dart,Performance,Functional Programming,Dart,在Dart中使用纯功能风格(无副作用)是否应该获得性能提升?天真地说,我会期望相反的结果,但我想可能会有更多的优化机会 举个例子,想象一个向量类可以这样实现: class-Vec{ 最终数值x,y,z; Vec(this.x,this.y,this.z); 向量添加(向量v)=>新向量(x+v.x,y+v.y,z+v.z); } 最终x=新的向量(1,2,3)。添加(新向量(4,5,6)); 与这样的实现相比: class-Vec{ 数值x,y,z; Vec(this.x,this.y,thi

在Dart中使用纯功能风格(无副作用)是否应该获得性能提升?天真地说,我会期望相反的结果,但我想可能会有更多的优化机会

举个例子,想象一个向量类可以这样实现:

class-Vec{
最终数值x,y,z;
Vec(this.x,this.y,this.z);
向量添加(向量v)=>新向量(x+v.x,y+v.y,z+v.z);
}
最终x=新的向量(1,2,3)。添加(新向量(4,5,6));
与这样的实现相比:

class-Vec{
数值x,y,z;
Vec(this.x,this.y,this.z);
Vec add(Vec v){x+=v.x;y+=v.y;z+=v.z;返回此;}
}
var x=新的向量(1,2,3)。添加(新向量(4,5,6));
这将创建一个更少的
Vec
对象。(显然,可能有一种
add(x,y,z)
方法来创建更少的
Vec
,但我认为添加的向量在现实生活中不是常量。)

据我所知,在Javascript虚拟机中,额外的对象创建相对昂贵,您不希望在不需要的时候创建新对象。如果这是C++,我希望在堆栈上有很多VEC对象,我希望这两个对象之间的差异可以被优化。
我认为纯函数风格的主要优化增益是并行性,这可能不适用于Dart VM。

在Dart中使用运算符就像调用方法一样。隐式操作数转换不会导致性能开销

我相信虚拟机是一个很好的解包简单对象并将它们保留在堆栈上的工具,尤其是在所有成员都是最终成员的情况下。因此,对于热代码,不应该因为创建了额外的对象而对垃圾收集器造成额外的压力

但正如马辛所说,最好的确定方法是分析这一点

也许可以看看源代码(这是一个简单的光线跟踪器)。我很确定这会对3D点和向量使用操作符重载。这将让您了解javascript与Dart的性能。您甚至可以删除+运算符调用,并用add()方法替换它们,以查看是否存在很大差异。(这可能比尝试创建微观基准更有用)


另外——也许你应该改变这个问题的标题——这不是关于。尽管Dart有一系列函数式方法,如map()和fold(),但它不支持纯函数式编程,因为它不支持正确的尾部调用,这意味着纯函数式程序会导致堆栈溢出。

好的,我继续进行了快速测试。基本上,我只是根据每个实现添加了十亿个向量。功能性的一个花费了大约三倍的时间。因此,看起来,至少目前,对象创建没有得到优化

void main(){
常数N=100000000;
int i=0;
var v=新的向量向量(0,0,0);
而(i

我还尝试了一个语义类似于
add(num,num,num)
的实现,而不是
add(newvec(num,num,num))
,从而消除了另一个临时对象。这甚至更快,但只是稍微快一点;这让我相信编译器确实能够部分优化特定的临时对象创建。

为什么不分析它呢?我想可能有人已经知道了。如果没有人问,我会问。一般来说,这类问题往往比较复杂,除非是专门针对特定的问题而优化的。你也可以阅读实现者对他们选择的优化所说的话。我很确定,在技术上,以纯功能风格编程而不消除尾部是可能的,这只是令人不快,因为程序员必须处理缺乏尾部的问题。此外,对于有界问题,纯函数风格是可以实现的,而无需例如蹦床。当然,这是可能的-只要你小心堆栈,并在未来(({…})调用中四处散布。但在现实中,即使是很小的程序,编写代码也将是一场噩梦。现在我写了“[Dart]不支持纯函数式编程”。你能想出一个更好的方法来描述这一点吗?我认为我所说的符合“纯功能”的定义,特别适用于我给出的示例,不一定(甚至不一定)适用于整个程序。将数据成员x、y和z声明为final排除了更新的可能性,不是吗?我根本没有谈论操作符重载方面的意思。我将编辑这个问题以消除它,我认为这将使问题更清楚。我还删除了一些“纯粹”的说法并加以澄清。这些类型的微观基准可能会产生非常误导性的结果。我想如果你给gcc-O3一个类似的基准测试,它将被简化为一个打印调用,并丢弃整个循环,因为它可以推断出v的值。您可能想查看邮件列表。以下是一位V8/Dart虚拟机开发人员关于微基准测试的谈话中的一些内容。要点已被采纳,谢谢您的链接。这也是我不想亲自描述它的原因之一。但另一方面,我希望找到优化器是否能够实现这些功能,也许我做到了。如果我能避免的话,我不想把每件事都实现两次来真正地描述它。在我看来,功能性风格此时不太可能带来一些期望的性能优势。