I have this code that works when I’m not running benchmark
.
require "big"
def prime?(n)
return n | 1 == 3 if n < 5
return false if n.gcd(6) != 1
p = typeof(n).new(5)
until p > Math.isqrt(n)
return false if n.divisible_by?(p) || n.divisible_by?(p+2)
p += 6
end
true
end
p = 7919 # < 2**16
puts "Is #{p} prime? #{prime? p}"
p = 982451653 # < 2**32
puts "Is #{p} prime? #{prime? p}"
p = 4294967311 # > 2**32
puts "Is #{p} prime? #{prime? p}"
p = 9223372036854775783i64 # largest I64
puts "Is #{p} prime? #{prime? p}"
p = 12345678901234567891u64 # a UInt64
puts "Is #{p} prime? #{prime? p}"
p = "7000768250000000000000".to_big_i # a BigInt
puts "Is #{p} prime? #{prime? p}"
=======================
Is 7919 prime? true
Is 982451653 prime? true
Is 4294967311 prime? true
Is 9223372036854775783 prime? true
Is 12345678901234567891 prime? true
Is 7000768250000000000000 prime? false
I can benchmark it using benchmark
only if I put the code at the end.
p = 7919 # < 2**16
puts "Is #{p} prime? #{prime? p}"
p = 982451653 # < 2**32
puts "Is #{p} prime? #{prime? p}"
p = 4294967311 # first prime > 2**32
puts "Is #{p} prime? #{prime? p}"
p = 9223372036854775783i64 # largest I64
puts "Is #{p} prime? #{prime? p}"
p = 12345678901234567891u64 # a UInt64
puts "Is #{p} prime? #{prime? p}"
p = "7000768250000000000000".to_big_i # a BigInt
puts "Is #{p} prime? #{prime? p}"
Benchmark.ips do |b|
print "\np = #{p}"
b.report("primep?") { prime?(p) }
puts
end
=====================
Is 7919 prime? true
Is 982451653 prime? true
Is 4294967311 prime? true
Is 9223372036854775783 prime? true
Is 12345678901234567891 prime? true
Is 7000768250000000000000 prime? false
p = 7000768250000000000000
primep? 78.67M ( 12.71ns) (± 2.93%) 0.0B/op fastest
But when I put the benchmark code at the top like this I get this type of compiler error.
p = 7919 # < 2**16
puts "Is #{p} prime? #{prime? p}"
Benchmark.ips do |b|
print "\np = #{p}"
b.report("primep?") { prime?(p) }
puts
end
=============
➜ crystal run --release primalitytestnew.cr --error-trace
In primalitytestnew.cr:64:28
64 | b.report("prime?") { prime?(p) }
^-------
Error: instantiating 'prime?((Int64 | UInt64))'
In primalitytestnew.cr:9:25
9 | return false if n.gcd(6) != 1
^
Error: ambiguous call, implicit cast of 6 matches all of Int64, UInt64
So where I’m doing the benchmark (its position in the code) causes this error.
I assume this is a bug?