<commit_before>import akka.actor.{Actor, ActorRef, ActorSystem, Props}
import scala.concurrent.Future
import scala.util.Random
import scala.math._

case class Data(idx: Int, data: Array[Double])
case class Create(idx: Int)
case class AvgResult(idx: Int, avg: Double)
case object Start
case object Done

object Safe extends App {
  val start = System.currentTimeMillis
  
  val system = ActorSystem("TestSys")
  implicit val disp = system.dispatcher
  
  // some expensive computation
  def exp(a: Array[Double]) = {
    var res = 0.0;
    var i = 0;
    while (i < a.length) {
      var j = 0;
      while (j < a.length) {
        res += a(i) + a(j) / 2
        j += 1;
      }
      i += 1;
    }
    
    res / a.length
  }
  
//  runActors()
  runFutures()
//  runSeq()
  
  def runSeq() = {
    val data = (1 to 1000) map { i => {
//      println("Creating " + i) 
      (i, Array.fill(2048) { Random.nextDouble }) }
    }
    val res = data map { d => {
      val avg = exp(d._2)
//      println("Average (" + d._1 + ") = " + avg)
      (d._1, avg) }
    }
    system.shutdown();
    println("Finished in " + (System.currentTimeMillis - start) + " millis")
  }
  
  def runFutures() = {
    def create(i: Int) = Future {
//      println("Creating " + i)
      (i, Array.fill(2048) { Random.nextDouble })
    }
    
    def avg(f: Future[(Int, Array[Double])]) = f map {t => (t._1, exp(t._2)) }
    
    val res = Future.traverse(1 to 1000)( i => avg(create(i)))
    
    res onSuccess {
      case a => {
//        a foreach { println(_) }
        system.shutdown();
        println("Finished in " + (System.currentTimeMillis - start) + " millis")
      }
    }
  }
  
  def runActors() = {
    system.actorOf(Props[Master]) ! Start
    system.awaitTermination()
  
    println("Finished in " + (System.currentTimeMillis - start) + " millis")
  }
}

class Master extends Actor {
  var i = 1000;
  
  def receive = {
    case Start => (1 to i) foreach { i =>
      context.actorOf(Props(new CreateActor(self))) ! Create(i)
    }
    case Done => {
      i = i - 1
      if (i <= 1) context.system.shutdown()
    }
  }
}

class CreateActor(parent: ActorRef) extends Actor {
  val avgActor = context.actorOf(Props[AvgActor])
  def receive = {
    case Create(i) => avgActor ! Data(i, Array.fill(2048) { Random.nextDouble })
    case AvgResult(i, avg) => parent ! Done
    case _ => println("Unknown request to CreateActor !!!")
  }
}

class AvgActor extends Actor {
  def receive = {
    case Data(i, d) => sender ! AvgResult(i, Safe.exp(d))
    case _ => println("Unknown request to AvgActor !!!")
  }
}<commit_msg>Use FFT for a slightly more realistic comparison<commit_after>package safe

import akka.actor.{Actor, ActorRef, ActorSystem, Props}
import scala.concurrent._
import scala.util.Random
import scala.math._
import safe.math._

case class Data(data: Seq[Double])
case class AvgResult(avg: Double)
case object Create
case object Start

// Silly test app for comparing standard code, futures, and actors
object Safe extends App {
  val start = System.currentTimeMillis
  
  val system = ActorSystem("TestSys")
  implicit val disp = system.dispatcher
  
//  runActors()
  runFutures()
//  runSeq()
  
  def avg(a: Seq[Complex]) = a.sum.re / a.length
  
  def randomData(n: Int) = Seq.fill[Double](n) { Random.nextDouble() }
  
  def runSeq() = {
    val data = (1 to 100) map { _ => randomData(2048) }
    val res = data map { d =>
      avg(FFT.fft(d))
    }
//    system.shutdown();
    println(res.sum + ", " + res.size)
    println("Finished in " + (System.currentTimeMillis - start) + " millis")
  }
  
  def runFutures() = {
    
    def futData = future { randomData(1024) }
    
    def futFft(f: Future[Seq[Double]]) = f map { v => FFT.fft(v) }
    
    def futAvg(f: Future[Seq[Complex]]) = f map { t => avg(t) }
    
    val res = Future.traverse(1 to 100)( _ => futAvg(futFft(futData)) )
    
    res onSuccess {
      case a => {
    	println(a.sum + ", " + a.size)
        system.shutdown();
        println("Finished in " + (System.currentTimeMillis - start) + " millis")
      }
    }
    
  }
  
  def runActors() = {
    system.actorOf(Props[Master]) ! Start
    system.awaitTermination()
  
    println("Finished in " + (System.currentTimeMillis - start) + " millis")
  }
}

class Master extends Actor {
  var i = 100;
  val a = new Array[Double](100)
  
  def receive = {
    case Start => (1 to i) foreach { i =>
      context.actorOf(Props(new CreateActor(self))) ! Create
    }
    case AvgResult(avg) => {
      i = i - 1
      a(i) = avg
      if (i <= 0) {
        println(a.sum + ", " + a.size)
        context.system.shutdown()
      }
    }
  }
}

class CreateActor(parent: ActorRef) extends Actor {
  val avgActor = context.actorOf(Props[AvgActor])
  def receive = {
    case Create => avgActor ! Data(Safe.randomData(2048))
    case AvgResult(avg) => parent ! AvgResult(avg)
    case _ => println("Unknown request to CreateActor !!!")
  }
}

class AvgActor extends Actor {
  def receive = {
    case Data(d) => sender ! AvgResult(Safe.avg(FFT.fft(d)))
    case _ => println("Unknown request to AvgActor !!!")
  }
}
{'fraction_non_alphanumeric': 0.1460717749757517, 'fraction_numerical': 0.013579049466537343, 'mean_word_length': 2.541208791208791, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 30, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4639797', 'n_tokens_mistral': 1887, 'n_tokens_neox': 1819, 'n_words': 453}