Advertisement
Guest User

Speedtest

a guest
Jan 5th, 2018
349
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Scala 2.48 KB | None | 0 0
  1. #!/usr/bin/env amm
  2.  
  3. /**
  4. Script to perform speedtest using multiple parallel threads.
  5.  
  6. This is written using Ammonite: http://ammonite.io/#ScalaScripts
  7.  
  8. Ammonite can be installed using the following command:
  9.  
  10. sudo curl -L -o /usr/local/bin/amm https://git.io/vdNv2 && sudo chmod +x /usr/local/bin/amm && amm
  11.  
  12. To run the script first make it executable:
  13.  
  14. chmod a+x speedtest.sc
  15.  
  16. To run with default parameters:
  17.  
  18. ./speedtest.sc
  19.  
  20. To override parameters you need to add -- followed by extra arguments
  21.  
  22. --parallels 4
  23.   Number of threads
  24.  
  25. --url
  26.   URL to download
  27.  
  28. --periods 5
  29.   Number of periods
  30.  
  31. Example:
  32.  
  33. ./speedtest.sc -- --periods 10
  34.  
  35. */
  36.  
  37. val bufferSize = 1*1024*1024
  38.  
  39. sealed trait ChannelData
  40. case class SpeedData(thread: Int, time: Long, size: Long) extends ChannelData
  41. case class Done(thread: Int) extends ChannelData
  42.  
  43. val channel = new scala.concurrent.Channel[ChannelData]
  44.  
  45. def downloadOnce(thread: Int, urlString: String) = new Thread {
  46.   override def run: Unit = {
  47.     val buffer = new Array[Byte](bufferSize)
  48.     val url = new java.net.URL(urlString)
  49.     val stream = url.openStream
  50.     var bytesRead = 0
  51.     def loop: Unit = stream.read(buffer) match {
  52.       case n if n <= 0 =>
  53.         channel.write(Done(thread))
  54.       case n =>
  55.         channel.write(SpeedData(thread,System.currentTimeMillis,n))
  56.         loop
  57.     }
  58.     loop
  59.   }
  60. }.start
  61.  
  62. @main
  63. def main(parallels: Int = 4, url: String = "http://ookla1.kviknet.dk:8080/download?nocache=x&size=500000000", periods: Int = 5) = {
  64.   println(f"Downloading from $url using $parallels threads.")
  65.   val begin = System.currentTimeMillis
  66.   for(n <- 1 to parallels) downloadOnce(n,url)
  67.   val builder = new scala.collection.immutable.VectorBuilder[SpeedData]
  68.   var doneCount = 0
  69.   while(doneCount < parallels) {
  70.     channel.read match {
  71.       case sd @ SpeedData(_,_,_) => builder += sd
  72.       case Done(thread) => doneCount = doneCount + 1
  73.     }
  74.   }
  75.   val end = System.currentTimeMillis
  76.   val data = builder.result
  77.   val total = data.map(_.size).sum
  78.   println(f"Downloaded $total bytes in ${end-begin} ms = ${total*8/(end-begin)/1000} Mbps.")
  79.   def groupFun(t: Long) = (((t-begin).toDouble / (end-begin))*periods).toInt
  80.   val groupedData = data.groupBy( d => groupFun(d.time)).mapValues(_.map(_.size).sum)
  81.   for(n <- 1 to periods) {
  82.     val size = groupedData.get(n-1).getOrElse(0L)
  83.     println(f"Period $n downloaded $size bytes in ${(end-begin)/periods} ms = ${size*8/((end-begin)/periods)/1000} Mbps.")
  84.   }
  85. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement