Last active
July 31, 2016 18:05
-
-
Save twistedpair/58414ee3237544eaf54a787a59f656c6 to your computer and use it in GitHub Desktop.
Simple performance benchmark for block post: https://lustforge.com/2016/05/08/modulo-operator-performance-impact/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
Simple benchmark of different ways to do modulo | |
- Numbers collected on a 4Ghz i7-4790K, 8 core AMD, 32GB PC3 19200 ram, SSD | |
- Scala 2.11.8 | |
- Java 1.8.0_91 | |
# scalac mod_perf.scala && scala ModPerf | |
**/ | |
object ModPerf extends App { | |
final val N = 1000000 | |
final val RandInts:Array[Int] = Array.fill(N){scala.util.Random.nextInt(1000)+2000000000} // big values, more expensive | |
final val RandDoubles:Array[Double] = Array.fill(N){scala.util.Random.nextDouble * 2000000000} | |
// This isn't very functional. Not passing functions, so we're not measuring "f.apply()" overhead | |
// Not storing output, as again I don't want to measure that aspect | |
// Not using mapping of collections, fors or iterators - don't want to measure their overhead | |
// Similar proportion of time taken when using RandInts(_ % b), for comprehension, etc | |
def timedOldDouble(n:Int):Long = { | |
val start = System.nanoTime() | |
val d:Double = 61d | |
val b:Double = 8d | |
var i =0 // cheaper than using a for iterator, comprension, or collection mapping | |
while (i < n) { | |
RandDoubles(i) % b | |
i+=1 | |
} | |
val deltaNanos = System.nanoTime() - start | |
deltaNanos | |
} | |
def timedOldInt(n:Int):Long = { | |
val start = System.nanoTime() | |
val d:Int = 61 | |
val b:Int = 8 | |
var i =0 | |
while (i < n) { | |
RandInts(i) % b | |
i+=1 | |
} | |
val deltaNanos = System.nanoTime() - start | |
deltaNanos | |
} | |
def timedPow2(n:Int):Long = { | |
val start = System.nanoTime() | |
val d:Int = 61 | |
val b:Int = 8-1 | |
var i =0 | |
while (i < n) { | |
RandInts(i) & b | |
i+=1 | |
} | |
val deltaNanos = System.nanoTime() - start | |
deltaNanos | |
} | |
// warmpup pass | |
timedOldDouble(N) | |
timedOldInt(N) | |
timedPow2(N) | |
// actual run | |
val ns1 = timedOldDouble(N) | |
val ns2 = timedOldInt(N) | |
val ns3 = timedPow2(N) | |
// Basic stats | |
val mean1 = ns1.toDouble/N.toDouble | |
val mean2 = ns2.toDouble/N.toDouble | |
val mean3 = ns3.toDouble/N.toDouble | |
println (s"FModDoubles ran in $ns1 ns, average: ${mean1} ns") | |
println (s"IRemIntegers ran in $ns2 ns, average: ${mean2} ns") | |
println (s"ModPow2 ran in $ns3 ns, average: ${mean3} ns") | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment