object isValidUuid {
val sample = "f40473b8-9924-2a9a-bd82-7432191f2a75"
val len = sample.length
val dashIndices = sample.indices.filter(sample(_) == '-')
def apply(string: String) = {
string.length == len && dashIndices.forall(string(_) == '-')
}
}
def isValidUuid(string: String) = {
//f40473b8-9924-2a9a-bd82-7432191f2a75
val sample = "f40473b8-9924-2a9a-bd82-7432191f2a75"
val len = sample.length
val dashIndices = sample.indices.filter(sample(_) == '-')
string.length == len && dashIndices.forall(string(_) == '-')
}
Did the object and function isValidUuid do exactly the same thing,
or object will be faster,because function calculate len and dashIndices every time?
This scala code:
object O {
val i = 1
def foo = {
i
}
def bar = {
val x = 1
x
}
}
Compiles to this java:
public class _$$anon$1$O$ {
private final int i;
public int i() {
return this.i;
}
public int foo() {
return this.i();
}
public int bar() {
final int x = 1;
return x;
}
{
this.i = 1;
}
}
// lazy object initialization omitted
As you can see, all values inside the function are transpiled into local variables, while values inside the object are class fields and they are initialized only once (when object is initialized). I omitted object initialization code for clarity.
Check my scala-to-java tool, it helps to understand how scala works in such cases.
You can easy test this, adding sleep to your lenght calculation
object isValidUuidObj {
val sample = "f40473b8-9924-2a9a-bd82-7432191f2a75"
val len = {
Thread.sleep(1000)
sample.length
}
val dashIndices = sample.indices.filter(sample(_) == '-')
def apply(string: String) = {
string.length == len && dashIndices.forall(string(_) == '-')
}
}
def isValidUuid(string: String) = {
//f40473b8-9924-2a9a-bd82-7432191f2a75
val sample = "f40473b8-9924-2a9a-bd82-7432191f2a75"
val len = {
Thread.sleep(1000)
sample.length
}
val dashIndices = sample.indices.filter(sample(_) == '-')
string.length == len && dashIndices.forall(string(_) == '-')
}
Yes, object will be faster, but I don't think that in your case this difference is important.
You'd better keep all constants in object (magic numbers/strings are always bad idea), while using object for calculations is not a clean solution.
I have function like this
def jsonFlatten(obj: JsValue, coun: JsObject = Json.obj(), pref: String = ""): JsObject = {
var con = coun
var kel = ""
var el: JsValue = Json.obj()
obj match {
case JsObject(_) =>
var ob = obj.validate[JsObject].get
ob.value.foreach({
case (k, v) =>
if (pref != "") {
kel = pref + "." + k
} else {
kel = k
}
el = v
el match {
case JsObject(_) =>
con = jsonFlatten(el, con.++(con), kel)
case JsArray(_) =>
con = jsonFlatten(el, con.++(con), kel)
case _ =>
con = con.+(kel -> el)
}
})
case _ =>
}
return con
}
That function called on another iteration within thread and I want to optimize this function because it takes lot time (around 300ms) and I have to call lot of that function in iteration.
Is there any suggestion how to optimize that function with concurrency or effective recursion ?
Thanks
as
I'm just beginner in scala but experienced in Java and C++, now I want to use akka actor model to implement the parallel Conway's Game of Life. My thought is create a 50*50 grid, each cell is an actor, and passing messages among actors to update. Here is the way I create the actors:
class World(row: Int, col: Int, step: Int) extends Actor {
val random = new Random() //generate the alive or dead cell for the game
val cellgrid = new World(row, col, step)
def receive = {
case Start => {
for(gridrow <- 0 until row) {
for(gridcol <- 0 until col) {
context.actorOf(Props(new Grid(random.nextBoolean, gridrow, gridcol, row, col, step)))
}
}
for (gridrow <- 0 until row) {
for (gridcol <- 0 until col) {
sender ! Compare()
}
}
}
case Done(gridrow, gridcol, alive) => {
for(gridrow <- 0 until row) {
for(gridcol <- 0 until col) {
if(alive) print("* ")
else print(" ")
}
print("\n")
}
sender ! Stop
}
case Stop => {context.stop(self); println("Stopped the actor system!")}
case _ => context.stop(self)
}
}
But that causes a problem. Since I create so many Grid classes, I'm having trouble call the neighbor actors. Here is the Grid class:
class Grid(var life: Boolean, gridrow: Int, gridcol: Int, row: Int, col: Int, step: Int) extends Actor {
val alive = life
var numNeighbors = 0
var currentStep = 0
val desiredSteps = step
val count = Array(0,0)
val countsuround = Array(0,0)
for (neighbourX <- gridrow - 1 to gridrow + 1) {
if (neighbourX >= 0 && neighbourX < col) {
for (neighbourY <- gridcol - 1 to gridcol + 1) {
if (neighbourY >= 0 && neighbourY < row && (neighbourX != row && neighbourY != col))
numNeighbors = numNeighbors + 1
}
}
}
def receive = {
case Compare() => {
for (neighbourX <- gridrow - 1 to gridrow + 1) {
if (neighbourX >= 0 && neighbourX < col) {
for (neighbourY <- gridcol - 1 to gridcol + 1) {
if (neighbourY >= 0 && neighbourY < row && (neighbourX != row && neighbourY != col))
sender ! Record(life, currentStep) //Here I need to pass messages to my neighbors
}
}
}
}
case Record(alive,step) => {
if(alive == true){
count(step%2) += 1
}
countsuround(step%2) += 1
self ! Check()
}
case Check() => {
if(countsuround(currentStep%2) == numNeighbors) {
if(count(currentStep%2) ==3 ||life == true && count(currentStep%2) == 2)
life = true
else
life = false
count(currentStep%2) =0; countsuround(currentStep%2) = count(currentStep%2)
currentStep += 1
if(desiredSteps <= currentStep + 1)
sender ! Stop
else {
sender ! Done(gridrow, gridcol, alive)
//context.stop(self)
}
}
}
}
}
Please take a look at the Compare case in the receive function, at the end of that, I need to send messages Record to my neighbors, but I can't find a proper way to talk, I don't have any index of neighbors (like (neighborX, neighborY).Record(life, currentStep)). Please help me, I've stuck here for several weeks. Thanks!!!
Here is a full working example with some comments.
import akka.actor._
import scala.concurrent.duration._
object GameOfLife extends App {
val system = ActorSystem("game-of-life")
implicit val ec = system.dispatcher // implicit ExecutionContext for scheduler
val Width = 20
val Height = 20
// create view so we can send results to
val view = system.actorOf(Props(classOf[View], Width, Height), "view")
// create map of cells, key is coordinate, a tuple (Int, Int)
val cells = (for { i <- 0 until Width; j <- 0 until Height } yield {
val cellRef = system.actorOf(Props[Cell], s"cell_$i-$j") // correct usage of Props, see docs for details
((i,j), cellRef)
}).toMap
// we need some helpers to work with grid
val neighbours = (x:Int, y:Int) => Neighbours(
for (i <- x - 1 to x + 1; j <- y - 1 to y + 1; if ((i,j) != (x,y))) yield {
cells( ( (i + Width) % Width, (j + Height) % Height) )
}
)
for { i <- 0 until Width; j <- 0 until Height } { // notice that this loop doesn't have yield, so it is foreach loop
cells((i,j)) ! neighbours(i,j) // send cell its' neighbours
}
// now we need to synchronously update all cells,
// this is the main reason why suggested model (one actor - one cell) is probably not the most adequate
for { i <- 0 until Width; j <- 0 until Height } {
cells((i,j)) ! SetState(alive = util.Random.nextBoolean, x = i, y = j)
}
// for simplicity I assume that update will take less then update time
val refreshTime = 100.millis
system.scheduler.schedule(1.second, refreshTime) {
view ! Run
for { i <- 0 until Width; j <- 0 until Height } {
cells((i,j)) ! Run
}
}
}
class View(w:Int, h:Int) extends Actor {
var actorStates: Map[(Int,Int), Boolean] = Map()
def receive:Receive = {
case Run => actorStates = Map.empty
case UpdateView(alive, x, y) =>
actorStates = actorStates + (((x,y), alive))
if (actorStates.size == w * h) {
for { j <- 0 until h } {
for(i <- 0 until w) {
if(actorStates((i,j))) {
print("x ")
} else {
print(". ")
}
}
println()
}
}
}
}
class Cell extends Actor {
var neighbours:Seq[ActorRef] = Seq()
var neighbourStates: Map[ActorRef, Boolean] = Map() // Map.empty[Map[ActorRef, Boolean]] is better
var alive:Boolean = false
var previousState:Boolean = false
var x:Int = 0
var y:Int = 0
def receive : Receive = {
case Run =>
neighbourStates = Map.empty
previousState = alive
neighbours.foreach(_ ! QueryState)
case SetState(alive,x,y) =>
this.alive = alive
this.x = x
this.y = y
case Neighbours(xs) =>
neighbours = xs
case QueryState =>
sender ! NeighbourState(alive = previousState)
case NeighbourState(alive) =>
neighbourStates = neighbourStates + ((sender, alive))
// this is tricky when all senders has send you their states it doesn't mean that you can mutate your own,
// they could still may request your internal state, will use hackish previousState
if (neighbourStates.size == 8) { // total of 8 neighbours sent their states, we are complete with update
val aliveMembers = neighbourStates.values.filter(identity).size
aliveMembers match {
case n if n < 2 => this.alive = false
case 3 => this.alive = true
case n if n > 3 => this.alive = false;
case _ => // 2, state doesn't change
}
context.actorSelection("/user/view") ! UpdateView(this.alive, x, y)
}
}
}
case class SetState(alive:Boolean, x:Int, y:Int)
case class Neighbours(xs:Seq[ActorRef])
case object QueryState
case object Run
case class NeighbourState(alive:Boolean)
case class UpdateView (alive:Boolean, x:Int, y:Int)
Count lines in a file (With BufferedInputStream) in Scala.
object CountLinesScala {
def main(args: Array[String]) {
val c = countLines("C:/.../Motifs/mrr569.fasta")
println(c)
}
def countLines(filename: String): Int = {
val is = new BufferedInputStream(new FileInputStream(filename))
try {
val c = Array.ofDim[Byte](1024)
var count = 0
var readChars = 0
var empty = true
while ((readChars = is.read(c)) != -1) {
empty = false
for (i <- 0 until readChars if c(i) == '\n') {
count=count +1
}
}
if ((count == 0 && !empty)) 1 else count
} finally {
is.close()
}
}
}
its not working, Why ?
i click run but there is no reaction, and no Errors !
You code is not working because the type of an assignation is Unit and you are comparing Unit to an Int (-1) which can never be equal, therefore your while loop never exits.
More specifically, this expression has type Unit
(readChars = is.read(c))
if you want to fix your version of the program you could define an internal function doRead
def doRead: Int = {
readChars = is.read(c)
readChars
}
and use that in your while loop
while (doRead != -1) {
empty = false
for (i <- 0 until readChars if c(i) == '\n') {
count=count +1
}
}
the final code for countLine would look like
def countLines(filename: String): Int = {
val is = new BufferedInputStream(new FileInputStream(filename))
try {
val c = Array.ofDim[Byte](1024)
var count = 0
var readChars = 0
var empty = true
def doRead: Int = {
readChars = is.read(c)
readChars
}
while (doRead!= -1) {
empty = false
for (i <- 0 until readChars if c(i) == '\n') {
count=count +1
}
}
if ((count == 0 && !empty)) 1 else count
} finally {
is.close()
}
}
However I advise you not to write Scala code like this. As was answered by brian, the most idiomatic way to write this would be to use the scala standard library and write
scala.io.Source.fromFile("C:/.../Motifs/mrr569.fasta").getLines.size
Then your original program would become
import scala.io.Source
object CountLinesScala {
def main(args: Array[String]) {
val c = Source.fromFile("C:/.../Motifs/mrr569.fasta").getLines().size
println(c)
}
}
The standard library handles this nicely.
scala.io.Source.fromFile("C:/.../Motifs/mrr569.fasta").getLines.size
I have a class with several variables containing Integers and I want a method which increases one of them by a certain amount depending on the call.
case class Bank {
private var depo = 0
private var loan = 0
def deposit(amount: Int): Boolean = {
if(amount>0) {
depo += amount
true
} else false
}
def withdraw(amount: Int): Boolean = {
if(amount > 0 && amount <= balance) {
depo -= amount
true
} else false
}
def balance_=(b:Int) = {
if(b >= 0) {
if(b < depo) withdraw(depo-b) else deposit(b-depo)
} else false
}
def balance = depo
}
When I want to increase deposits, I just call
myBank.balance += 10
but when I now want to increase loan, I have to write an additional method, right?
Is there a possibility to write a method like
increaser(varToIncrease, amount)
Is that possible or even useful? Or do I have to write an "increaser"-method for every single var?
See if this is what you are looking for based on your additional comments:
case class Bank {
private var depo = 0
private var loans = 0
def deposit(amount: Int): Boolean = addTo(amount, depo += amount)
def loan(amount: Int): Boolean = addTo(amount, loans += amount)
private def addTo(amount:Int, func: => Unit):Boolean = {
if(amount > 0) {
func
true
}
else
false
}
def withdraw(amount: Int): Boolean = {
if(amount > 0 && amount <= balance) {
depo -= amount
true
} else false
}
def balance_=(b:Int) = {
if(b >= 0) {
if(b < depo) withdraw(depo-b) else deposit(b-depo)
} else false
}
def balance = depo
def loanAmount = loans
}
object BankTest{
def main(args: Array[String]) {
val b = new Bank
println("Starting amounts, " + b.balance + ", " + b.loanAmount)
b.deposit(10)
println(b.balance)
b.deposit(-1)
println(b.balance)
b.loan(100)
println(b.loanAmount)
b.loan(-50)
println(b.loanAmount)
}
}
I created two public functions to increase balance and loaned amount respectively. Then, I created an interval addTo function to handle the business logic of performing an operation to increase one of those vars.
You cannot increase the integer parameter inside another method. If you want to create an increaser method as you wanted, you have to pass in an immutable object into the method.