Lately I’ve been learning the ins and outs of the Scala language and I have to say, having programmed in Java for the past several years, that Scala is scratching where I itch. It is a lot to grasp and mind opening, but all-in-all I see Scala as what Java could have evolved to if they would have just been willing to ditch some backwards compatibility and fix some stuff rather than just adding more and more work-arounds.
Anyway, that’s not the point of this post. I wanted to post some cool loop examples I’ve been playing with in Scala.
In Java we have the standard incrementing for-loop:
for (int i = 0; i < 10; i++) {
...
}
In Scala we have something similar, but I believe more elegant:
for (i <- 0 until 10) {
...
}
However, with Java 1.5 we got the enhanced for-loop when we don’t care about indexes:
for (String s : listOfStrings) {
...
}
In Scala we do something similar, but with a more consistent syntax:
for (s <- listOfStrings) {
...
}
Or, we can go a step further with Scala since it’s a functional language we can get rid of the for loop entirely and use a friendly method available to us called “foreach” and pass each entry to another method:
listOfStrings.foreach(doSomething);
def doSomething(s:String):Unit = {
...
}
To me this is of significant appeal because we don’t end up with a bunch of embedded for-loop blocks in our methods we focus more on modular functionality to deal with the results of the iteration instead.
What happens if your incrementor e.g. is not i++ what happens if I wish to count up for example i+=2 OR I+= #some other integer
Simply modify the call to Range to step by 2:
for (i <- 0 until 10 by 2) {
…
}
Re performance.
Comparing performance I see unexpected results – any comments on the following.
Counting up with Int
for ( i:Int <- 0 to 500000000) { }
took 859ms
Counting up with Long is massively slower ..
for ( i: Long <- 0L to 500000000L) {}
took 5000ms
Counting down is much faster and about same timing with int or long
for ( i:Int <- 500000000 to 0 ) {}
took 341ms
for ( i:Long <- 500000000L to 0L ) {}
took 343ms
CPU : Core i5 M520
@John, that's interesting. I'll have to play around with that and see what's going on. Have you tried decompiling the code into Java and seeing what the code looks like and how it differs? That's what I would probably do to get a better idea of what the Scala compiler is doing behind the scenes.
How do I do:
float f;
for(f=2.0; f<=20.0; f+0.25) {
…
}
I dont see any room for the increment specially for float/double types ?
@Arjuns, it's actually quite elegant:
for (f <- 2.0 to 20.0 by 0.25) {
…
}
@John:
You should have done:
for (i: Long <- 500000000L to 0L by -1) {}
instead of:
for (i: Long <- 500000000L to 0L) {}
Latter doesn't do anything because 500000000L is greater than 0L.
for (i: Long <- 0L to 500000000L) {}
took 5000ms
for (i: Long <- 500000000L to 0L by -1) {}
took 7000ms when benchmarked
So counting down seems to be much slower than counting up