我可以在C#中创建模板样式的泛型常量uint吗?

时间:2013-09-20 05:20:38

标签: c# templates generics optimization

我似乎无法在C#中创建一个高性能的D-ary Heap类;硬编码的子女数量(BinaryHeapTernaryHeap等)似乎表现得更好。

我的BinaryHeapD-ary Heapd=2之间代码的唯一区别在于d是先前的const,而且readonly成员变量在后者(和readonly has no affect on performance)。

我猜测const版本可能会编译为一个位移操作,而成员变量版本可能会编译为memory-fetch + devision。

有没有办法可以像我这样声明我的班级:

 public class DaryHeap<T, const uint(d)> : IEnumerable<T> where T : IComparable<T>

其中 const uint(d) 会告诉编译器“d是编译时uint值”。因此,让D-ary Heapd=2的{​​{1}}表现与BinaryHeap相同。

2 个答案:

答案 0 :(得分:1)

当我尝试使用D-ary堆(12)时,我发现了类似的东西(在这些主题中未提及),然后放弃了。没有太多与D相关的值。 4和8是关于所有的。 16,很少。 2,不是真的:在我的测试中,4-ary 总是更快(即使在“不应该”的情况下)。我还测试了2的非幂,也没有提到,因为它们很糟糕。

所以我决定制作一些硬编码版本。这违反了一些编码原则,但由于性能是我首先使用D-ary堆的主要原因,因此不使D成为常数的性能损失仅仅是不可接受的。

基本上只有D的两个值很重要,因此复制/粘贴代码的数量实际上并不高。

答案 1 :(得分:1)

CLR泛型比C ++模板更受限制。

但是还有其他类型的模板。以T4为例。您可以将D-ary堆编写为T4模板,然后从中生成具体版本。我假设您使用Visual Studio,它可以自动与T4集成。这样可以保持DRY(因为您只修改模板本身)并且速度很快(因为您有最佳实现)。最好的部分是你可以使用真正的语言来生成代码,而不是像使用C ++模板那样使用元语言。