summaryrefslogtreecommitdiff
path: root/lib/prime.rb
diff options
context:
space:
mode:
authorMarc-Andre Lafortune <@marc-andre.ca>2020-12-05 00:20:39 -0500
committerMarc-André Lafortune <@marc-andre.ca>2020-12-09 00:40:09 -0500
commit1866d483dce614a02c5186bd0588b48a5041e55e ()
treef4f15b3a25fc9c217ea43598e57674e919092703 /lib/prime.rb
parentdea600046aa5895e745a8d655ff90616705e11a6 (diff)
[ruby/prime] Optimize `Integer#prime?`
Miller Rabin algorithm can be used to test primality for integers smaller than a max value "MaxMR" (~3e24) It can be much faster than previous implementation: ~100x faster for numbers with 13 digits, at least 5 orders of magnitude for even larger numbers (previous implementation is so slow that it requires more patience than I have for more precise estimate). Miller Rabin test becomes faster than previous implementation at somewhere in the range 1e5-1e6. It seems that the range 62000..66000 is where Miller Rabin starts being always faster, so I picked 0xffff arbitrarily; before that, or above "MaxMR", the previous implementation remains. I compared the `faster_prime` gem too. It is slower than previous implementation up to ~1e4. After that it becomes faster and faster compared to previous implementation, but is still slower than Miller Rabin starting at ~1e5 and up to MaxMR. Thus, after this commit, builtin `Integer#prime?` will be similar or faster than `faster_prime` up to "MaxMR". Adapted from of Stephen Blackstone [Feature #16468] Benchmark results and code: https://gist..com/marcandre/b263bdae488e76dabdda84daf73733b9 Co-authored-by: Stephen Blackstone <[email protected]>
Notes: Merged: https://.com/ruby/ruby/pull/3847
-rw-r--r--lib/prime.rb74
1 files changed, 74 insertions, 0 deletions
@@ -31,8 +31,14 @@ class Integer
end
# Returns true if +self+ is a prime number, else returns false.
def prime?
return self >= 2 if self <= 3
return true if self == 5
return false unless 30.gcd(self) == 1
(7..Integer.sqrt(self)).step(30) do |p|
@@ -43,6 +49,73 @@ class Integer
true
end
# Iterates the given block over all prime numbers.
#
# See +Prime+#each for more details.
@@ -156,6 +229,7 @@ class Prime
end
# Returns true if +value+ is a prime number, else returns false.
#
# == Parameters
#