Skip to content

Instantly share code, notes, and snippets.

@optician
Created June 16, 2016 21:58
Show Gist options
  • Save optician/f86abd01b05a60a536a5ceb374ef1f89 to your computer and use it in GitHub Desktop.
Save optician/f86abd01b05a60a536a5ceb374ef1f89 to your computer and use it in GitHub Desktop.
import org.scalameter._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.Duration
import scala.concurrent.{Await, ExecutionContext, Future}
object Main {
/*
Future.successful: 1170.1840314699998 ms ms
Future(): 1482.405004729999 ms ms
Single Threaded: 166.07368732000003 ms ms
Successful relative to apply = 0.7893821376319042
Successful relative to single threaded = 7.046173601331703
*/
val standardConfig = config(
Key.exec.minWarmupRuns -> 40,
Key.exec.maxWarmupRuns -> 80,
Key.exec.benchRuns -> 100,
Key.verbose -> true
) withWarmer new Warmer.Default
val N = 100
val futureListSize = 100000
def main(args: Array[String]) {
val time1 = standardConfig measure {
val fs = List.fill(futureListSize){
foo(
read = () => Future.successful("1"),
write = { s =>
s.toInt
Future.successful(())
}
)
}
Await.ready(Future.sequence(fs), Duration.Inf)
}
val time2 = standardConfig measure {
val fs = List.fill(futureListSize){
foo(
read = () => Future("1"),
write = { s =>
s.toInt
Future(())
}
)
}
Await.ready(Future.sequence(fs), Duration.Inf)
}
val time3 = standardConfig measure {
val fs = List.fill(futureListSize){
fooSingleThreaded(
read = () => "1",
write = { s =>
s.toInt
()
}
)
}
Await.ready(Future.sequence(fs), Duration.Inf)
}
println(s"Future.successful: $time1 ms")
println(s"Future(): $time2 ms")
println(s"Single Threaded: $time3 ms")
println(s"Successful relative to apply = ${time1.value / time2.value}")
println(s"Successful relative to single threaded = ${time1.value / time3.value}")
}
def foo(read: () => Future[String], write: String => Future[Unit])
(implicit topEc: ExecutionContext): Future[Unit] = {
def loop(state: Int): Future[Unit] = {
for {
text <- read()
x = text.toInt
newState = state + x
_ <- write(newState.toString)
_ <- {
if (newState == N) Future.successful(())
else loop(newState)
}
} yield {
()
}
}
loop(0)
}
def fooSingleThreaded(read: () => String, write: String => Unit)
(implicit topEc: ExecutionContext): Future[Unit] = {
def loop(state: Int): Unit = {
val text = read()
val newState = state + text.toInt
write(newState.toString)
if (newState == N) () else loop(newState)
}
Future(loop(0))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment