Shr*_*roy 6 f# discriminated-union
是的,这是一个微不足道的问题,但我找不到专家意见.
我正在使用计算表达式来排序服务器端进程.当我的函数具有相同的签名时,它会给我带来极大的帮助,因此我有一个区分的联合,其中定义了不同的组合.我有几个快速,初学者的问题.
DU可以选择的数量是否有建议的上限?目前我的DU有九个选项,但随着项目的进展,这个数字会增加.如果我在项目结束时达到30或40怎么办?
如果某些选项变得"长",可能会出现问题吗?目前,平均选项有大约四到五种基本类型 - 类似于 - bool * string * XElement * int * string但最长的选项具有以下定义:
bool*int*int*int*string*XElement*XElement*DateTime选项*DateTime选项*字符串*字典*字典
我不希望有这么长的选择.但是,我是否在为表现方面的痛苦世界做好准备?
提前致谢.
我认为如果数据类型的大小与F#编译器使用的数据类型的大小相似,你可以放心地假设事情会很好--F#编译器的性能是F#团队肯定看过的东西,所以我认为他们也做了一些实验,以确保他们使用的受歧视的工会有效地工作.
至于案件数量,SynExpr歧视联盟(见源代码)有50多个案例,所以我认为这应该没问题.
通过switch在整数上使用IL操作码来编译区分联合上的模式匹配,因此如果您想确定,可以尝试对其效率进行一些研究.此外,如果您只是match用来查找一个特定的案例,那么这应该只是一个整数比较,而不管其他案例的数量.
至于字段数,最长的情况SynExpr有7个字段,但我想你可以找到长度更长的其他DU.(我认为这个属性的一个更大的问题是可读性 - 因为属性是未命名的.所以我认为使用逻辑上属于大量属性的记录可能会更好.)
我认为你描述的DU的大小应该没问题,但我自己没有做过任何性能测试 - 所以如果你真的想确定,你需要测量它.(但正如我所说,我很确定这是已经作为F#编译器开发的一部分进行测试的东西)
如果内存为我服务,我相信在DUs上有很多案例/字段的深度嵌套模式匹配存在一些性能问题,但是这是2.0之前的版本,我相信他们修复了实现,以便当前这样的场景是经过充分优化,没有明显的性能问题.(对不起,没有引用).
但即使在优化的情况下,DUs也会消耗掉相当多的代码.因此,即使他们可能会执行,以及(可能更好)比任何等价手工编码的控制流程,还有就是,你可以堆栈溢出的可能性上的一个函数/方法的身体所发出的指令数量之多(但是这将是非常极端的情况,因为.NET默认堆栈大小约为1MB,但是,在非尾递归方法/函数涉及大DU的匹配时,它肯定会导致比平时更早的堆栈溢出,但同样不太可能达到你应该真的害怕这种情况).
我不认为它会改变性能特征(因为我们在任何一种情况下都讨论堆分配的对象),但是为了可维护性/可读性,有时可以将DU案例数据包装在一个记录类型中,以便命名数据字段和数据字段子集上的模式匹配更容易(例如,{Name="Stephen"}而不是(_,_,_,_,_,_,_,"Stephen",_,_,_,_,_)).(@TomasPetricek打败了我这个建议,没看到我第一次看到他的回答)