【问题标题】:Why in .Net HashHelpers.IsPrime is implemented in this way?为什么在.Net HashHelpers.IsPrime 中以这种方式实现?
【发布时间】:2018-11-28 23:41:54
【问题描述】:

查看 .NET System.Collections.Generic.Dictionary<T,T> 实现,我发现了一个方法 HashHelpers.IsPrime(n),它检查数字是否为素数。 我有点困惑,为什么他们使用非常简单的优化技术只测试从 3 开始的奇数。

(来自源代码)

int limit = (int)Math.Sqrt (candidate);
for (int divisor = 3; divisor <= limit; divisor+=2)
{
     if ((candidate % divisor) == 0)
          return false;
     }
return true;

因此,他们将检查次数从 3 次减少到了限制。但更优化的是根据Wikipedia 对数字 6*k-1,6*k+1 进行测试,将测试减少 3 次。而且我认为对于素性检验还有更优化和更快的解决方案。

我知道,特别是 Dictionary&lt;T,T&gt; 实现它并不那么重要,因为它仅在大型字典中调用,并且在调整大小时非常罕见。但总的来说,它是一个框架,非常受知名公司的欢迎。也许存在一些逻辑,或者我在这里看不到什么?谢谢。

【问题讨论】:

标签: c# .net algorithm primes


【解决方案1】:

我认为对于素性检验有更优化和更快的解决方案。

是的。

也许存在一些逻辑,或者我在这里看不到什么?

不。您已经准确地总结了情况。

你问:

为什么在 .Net HashHelpers.IsPrime 中以非最佳方式实现?

然后你回答你自己的问题:

我知道,特别是 Dictionary&lt;T,T&gt; 实现它并不那么重要,因为它仅在大型字典中调用,并且在调整大小时非常罕见。

所以你知道你的问题的答案。 它没有经过优化,因为足够快就定义为足够快,并且给定的算法足够快。

如果你想让它更快,嘿,它是开源的。去实现一个您更喜欢的算法,并提交您精心设计、准确和精确的经验性能测试的详细结果,清楚地表明对广泛使用的基础功能进行不必要的更改 在不重要且罕见的情况下,您的卓越性能算法证明了这一点。

如果这听起来像很多工作几乎没有任何好处,那么你知道你的问题的答案。收益不大的昂贵工作会被排在优先级列表的底部。

【讨论】:

  • 看起来素数实际上是预先计算的,因此该函数的使用是一次性的。不知道为什么它是公开的。
  • 我读到“足够快就是定义上足够快”,并且不必再向下滚动就知道这是 Eric Lippert 的帖子。我最喜欢你的一句话! :)
  • @AndersonPimentel:哈,这很有趣。不,我没有,但我以前写过哈希表,有时会带来灾难性的后果。我曾经在哈希表中造成了一个错误,导致 microsoft.com 陷入瘫痪,但那是在 1990 年代网络还没有那么大的时候。
  • @WillNess:由于该代码可能已经在产品中使用了二十年左右,因此我无法同意您的评估。如果有人在乎,它早就改了。或者也许我们只是没有等到后面的咬伤足够长的时间;你估计还需要多少年?
  • @WillNess:我在这里没有遵循你的思路。您似乎在说因为过去有人可能已经多等了几分钟让这段代码运行,所以我们应该现在更改它。为什么那个假设的人在 2005 年从冰箱里拿汽水的机会在 2018 年很重要?同样,如果它对您很重要,嘿,它是开源的。去更改它并提交一份详细分析,说明如果您对此更改有强烈的感觉,为什么应该接受它。
猜你喜欢
  • 1970-01-01
  • 2023-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-19
相关资源
最近更新 更多