Created
June 16, 2016 21:58
-
-
Save optician/f86abd01b05a60a536a5ceb374ef1f89 to your computer and use it in GitHub Desktop.
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
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