chrisdinn / brando

A Redis client written with Akka's IO package
Other
107 stars 24 forks source link

Performance improvement #48

Closed damienlevin closed 9 years ago

damienlevin commented 9 years ago

Switch from List to Vector to improve performance of append (http://docs.scala-lang.org/overviews/collections/performance-characteristics.html)

List

Done inserting list of 25000 in 1095 ms Done requesting list of 25000 in 6029 ms Done inserting list of 25000 in 464 ms Done requesting list of 25000 in 6218 ms Done inserting list of 25000 in 472 ms Done requesting list of 25000 in 6209 ms Done inserting list of 25000 in 457 ms Done requesting list of 25000 in 6250 ms Done inserting list of 25000 in 465 ms Done requesting list of 25000 in 6219 ms Done inserting list of 25000 in 479 ms Done requesting list of 25000 in 6180 ms Done inserting list of 25000 in 471 ms Done requesting list of 25000 in 5517 ms Done inserting list of 25000 in 458 ms Done requesting list of 25000 in 5931 ms

Vector

Done inserting list of 25000 in 1164 ms Done requesting list of 25000 in 253 ms Done inserting list of 25000 in 530 ms Done requesting list of 25000 in 132 ms Done inserting list of 25000 in 468 ms Done requesting list of 25000 in 98 ms Done inserting list of 25000 in 483 ms Done requesting list of 25000 in 95 ms Done inserting list of 25000 in 494 ms Done requesting list of 25000 in 100 ms Done inserting list of 25000 in 453 ms Done requesting list of 25000 in 105 ms Done inserting list of 25000 in 461 ms Done requesting list of 25000 in 102 ms Done inserting list of 25000 in 471 ms Done requesting list of 25000 in 98 ms

Test used:

package brando

import akka.util._

import akka.actor. import akka.pattern. import scala.concurrent. import scala.concurrent.duration.

object TestApp extends App with ReplyParser {

implicit val t = Timeout(300.seconds)

import scala.concurrent.ExecutionContext.Implicits.global val system = ActorSystem("system") val redis = system.actorOf(Brando("localhost", 6379))

def testRequest(list: Int*) { list.foldLeft(Future()) { case (res, size) ⇒ for { r ← res m ← { var start = 0L for { i ← { start = System.currentTimeMillis Future.traverse(1 to size) { i ⇒ redis ? Request("SADD", s"test-set-list-$size", s"el-$i") } } m ← { println(s"Done inserting list of $size in ${System.currentTimeMillis - start} ms") start = System.currentTimeMillis redis ? Request("SMEMBERS", s"test-set-list-$size") } p ← { println(s"Done requesting list of $size in ${System.currentTimeMillis - start} ms") redis ? Request("DEL", s"test-set-list-$size") } } yield (p)

      }
    } yield (m)
}

}

println("Global: Starting perf test...") try { // testRequest(1000, 5000, 10000, 15000, 20000, 25000, 30000, 35000) testRequest(25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000)

} catch { case e: Exception ⇒ e.printStackTrace } }

damienlevin commented 9 years ago

This PR resolves #47

chrisdinn commented 9 years ago

fix seems to imply the primary performance issue was appending to the end of a list interesting that could have such an impact!

chrisdinn commented 9 years ago

I think we can still beat 453ms to parse that list, but this is an awesome performance improvement. Thanks Damien!