This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Question about for

6 replies
Rodrigo Cano
Joined: 2009-03-22,
User offline. Last seen 42 years 45 weeks ago.
I was curious about the performance of the for in scala, I mean, with all its capability, I wanted to know if it was flexible enough to scale down to simple tasks and be "fast", so I did a little test to compare those simple
iterations between scala and java.
After the results, I am quite surprised, in my machine scala proved being 10 times slower than the same java operation. Well, at least thats what I think, so here I am posting my really simple code, so that you can tell me
if I did anything wrong, or these are the blunt results.

This is the scala code, wich I think is written in a natural scala way:

        var started = System.currentTimeMillis
        var justToReasign = 0

        for(times <- 0 until 2; index <- 0 until Int.MaxValue){
            justToReasign = index % 30
        }
        println("Total = " + (System.currentTimeMillis - started))

        started = System.currentTimeMillis
        val array = new Array[Int](10000000)
        array.foreach{ i =>
            justToReasign = i % 3
        }
        println("Total = " + (System.currentTimeMillis - started))
 
The Result is :

        Total = 45823
        Total = 181


And here would be the analogous java code:

        long start = System.currentTimeMillis();
        int justToReasign = 0;
        for (int i = 0; i < 2; i++) {
            for (int j = 0; j < Integer.MAX_VALUE; j++) {
                justToReasign = j % 30;
            }
        }
        System.out.println("Total = " + (System.currentTimeMillis() - start));

        start = System.currentTimeMillis();
        int[] array = new int[10000000];
        for (int i : array) {
            justToReasign = i / 3;
        }
        System.out.println("Total = " + (System.currentTimeMillis() - start));

With a nice result of:

       Total = 3626
       Total = 39

I would like to know if I am doing something wrong, beacuse the scala results were really high. I was all happy doing an image processing api in scala due to its flexibility and nicety, but I found that processing every pixel can be
reaaaaally slow in scala.

Thanks.
David Pollak
Joined: 2008-12-16,
User offline. Last seen 42 years 45 weeks ago.
Re: Question about for
Ridrigo,
Scala code can be made to run as fast as Java code, but you have to be aware of how Scala is different.
The for comprehension is not the same as a for loop in Java.  The for comprehension is compiled down to a  (0 until 2).foreach(times => (0 until Integer.MAX_VALUE).foreach(index => ...))
So, you've got a couple of functions in there.  That can impact performance until HotSpot sorts things out.
Talking about HotSpot sorting things out, your loop in Java will be eliminated by most HotSpot implementations.  No matter how much you loop (0 to 100, 0 to 1000, 0 to Integer.MAX_VALUE), the performance will be the same.
For performance intensive operations, I suggest putting everything in a while loop in Scala or a tail-recursive method.
Finally, benchmarking anything on the JVM is tough.  You have to call a method at least 10,000 times before HotSpot (in server mode) will optimize calls to the method.  There are a ton of other variables.
So, yes, you can make your Scala code perform as well as your Java code, but you have to write your Scala code like it was C code... then again, to maximize the performance of your Java code, you have to write it as if it was C code.
Thanks,
David

On Sun, Mar 22, 2009 at 3:21 PM, Rodrigo Cano <ioniviil@gmail.com> wrote:
I was curious about the performance of the for in scala, I mean, with all its capability, I wanted to know if it was flexible enough to scale down to simple tasks and be "fast", so I did a little test to compare those simple
iterations between scala and java.
After the results, I am quite surprised, in my machine scala proved being 10 times slower than the same java operation. Well, at least thats what I think, so here I am posting my really simple code, so that you can tell me
if I did anything wrong, or these are the blunt results.

This is the scala code, wich I think is written in a natural scala way:

        var started = System.currentTimeMillis
        var justToReasign = 0

        for(times <- 0 until 2; index <- 0 until Int.MaxValue){
            justToReasign = index % 30
        }
        println("Total = " + (System.currentTimeMillis - started))

        started = System.currentTimeMillis
        val array = new Array[Int](10000000)
        array.foreach{ i =>
            justToReasign = i % 3
        }
        println("Total = " + (System.currentTimeMillis - started))
 
The Result is :

        Total = 45823
        Total = 181


And here would be the analogous java code:

        long start = System.currentTimeMillis();
        int justToReasign = 0;
        for (int i = 0; i < 2; i++) {
            for (int j = 0; j < Integer.MAX_VALUE; j++) {
                justToReasign = j % 30;
            }
        }
        System.out.println("Total = " + (System.currentTimeMillis() - start));

        start = System.currentTimeMillis();
        int[] array = new int[10000000];
        for (int i : array) {
            justToReasign = i / 3;
        }
        System.out.println("Total = " + (System.currentTimeMillis() - start));

With a nice result of:

       Total = 3626
       Total = 39

I would like to know if I am doing something wrong, beacuse the scala results were really high. I was all happy doing an image processing api in scala due to its flexibility and nicety, but I found that processing every pixel can be
reaaaaally slow in scala.

Thanks.



--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp
Jorge Ortiz
Joined: 2008-12-16,
User offline. Last seen 29 weeks 4 days ago.
Re: Question about for
This might change if @specialized works out. Then Scala for-comprehensions might be closer to Java's for-loops in performance.

In the meantime, David is right. Use while loops or non-virtual tail-recursive methods.

--j

On Sun, Mar 22, 2009 at 5:06 PM, David Pollak <feeder.of.the.bears@gmail.com> wrote:
Ridrigo,
Scala code can be made to run as fast as Java code, but you have to be aware of how Scala is different.
The for comprehension is not the same as a for loop in Java.  The for comprehension is compiled down to a  (0 until 2).foreach(times => (0 until Integer.MAX_VALUE).foreach(index => ...))
So, you've got a couple of functions in there.  That can impact performance until HotSpot sorts things out.
Talking about HotSpot sorting things out, your loop in Java will be eliminated by most HotSpot implementations.  No matter how much you loop (0 to 100, 0 to 1000, 0 to Integer.MAX_VALUE), the performance will be the same.
For performance intensive operations, I suggest putting everything in a while loop in Scala or a tail-recursive method.
Finally, benchmarking anything on the JVM is tough.  You have to call a method at least 10,000 times before HotSpot (in server mode) will optimize calls to the method.  There are a ton of other variables.
So, yes, you can make your Scala code perform as well as your Java code, but you have to write your Scala code like it was C code... then again, to maximize the performance of your Java code, you have to write it as if it was C code.
Thanks,
David

On Sun, Mar 22, 2009 at 3:21 PM, Rodrigo Cano <ioniviil@gmail.com> wrote:
I was curious about the performance of the for in scala, I mean, with all its capability, I wanted to know if it was flexible enough to scale down to simple tasks and be "fast", so I did a little test to compare those simple
iterations between scala and java.
After the results, I am quite surprised, in my machine scala proved being 10 times slower than the same java operation. Well, at least thats what I think, so here I am posting my really simple code, so that you can tell me
if I did anything wrong, or these are the blunt results.

This is the scala code, wich I think is written in a natural scala way:

        var started = System.currentTimeMillis
        var justToReasign = 0

        for(times <- 0 until 2; index <- 0 until Int.MaxValue){
            justToReasign = index % 30
        }
        println("Total = " + (System.currentTimeMillis - started))

        started = System.currentTimeMillis
        val array = new Array[Int](10000000)
        array.foreach{ i =>
            justToReasign = i % 3
        }
        println("Total = " + (System.currentTimeMillis - started))
 
The Result is :

        Total = 45823
        Total = 181


And here would be the analogous java code:

        long start = System.currentTimeMillis();
        int justToReasign = 0;
        for (int i = 0; i < 2; i++) {
            for (int j = 0; j < Integer.MAX_VALUE; j++) {
                justToReasign = j % 30;
            }
        }
        System.out.println("Total = " + (System.currentTimeMillis() - start));

        start = System.currentTimeMillis();
        int[] array = new int[10000000];
        for (int i : array) {
            justToReasign = i / 3;
        }
        System.out.println("Total = " + (System.currentTimeMillis() - start));

With a nice result of:

       Total = 3626
       Total = 39

I would like to know if I am doing something wrong, beacuse the scala results were really high. I was all happy doing an image processing api in scala due to its flexibility and nicety, but I found that processing every pixel can be
reaaaaally slow in scala.

Thanks.



--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp

DRMacIver
Joined: 2008-09-02,
User offline. Last seen 42 years 45 weeks ago.
Re: Question about for

2009/3/23 Jorge Ortiz :
> This might change if @specialized works out. Then Scala for-comprehensions
> might be closer to Java's for-loops in performance.

It should be noted that Scala for comprehension are already largely
equivalent in performance to the Java foreach loop. The problem with
this sort of loop is very explicitly about boxing: Each use boxes the
integer being passed to the loop body, which is a real performance
killer.

John Nilsson
Joined: 2008-12-20,
User offline. Last seen 42 years 45 weeks ago.
Re: Question about for

On Sun, Mar 22, 2009 at 11:21 PM, Rodrigo Cano wrote:
>         for(times <- 0 until 2; index <- 0 until Int.MaxValue){
>             justToReasign = index % 30
>         }

Besides what was allready said about hotspot and other optimizations
that might affect the benchmark. Also concider that you might
accidentally measure class loading if this for comprehension
introduces new classes after your "started" has been set.

BR,
John

Naftoli Gugenheim
Joined: 2008-12-17,
User offline. Last seen 42 years 45 weeks ago.
Re: Question about for
Let us know how it compares to Java when you start timing after 10,000 iterations!

On Mon, Mar 23, 2009 at 3:50 PM, John Nilsson <john@milsson.nu> wrote:
On Sun, Mar 22, 2009 at 11:21 PM, Rodrigo Cano <ioniviil@gmail.com> wrote:
>         for(times <- 0 until 2; index <- 0 until Int.MaxValue){
>             justToReasign = index % 30
>         }

Besides what was allready said about hotspot and other optimizations
that might affect the benchmark. Also concider that you might
accidentally measure class loading if this for comprehension
introduces new classes after your "started" has been set.

BR,
John

Viktor Klang
Joined: 2008-12-17,
User offline. Last seen 1 year 27 weeks ago.
Re: Question about for


On Mon, Mar 23, 2009 at 8:50 PM, John Nilsson <john@milsson.nu> wrote:
On Sun, Mar 22, 2009 at 11:21 PM, Rodrigo Cano <ioniviil@gmail.com> wrote:
>         for(times <- 0 until 2; index <- 0 until Int.MaxValue){
>             justToReasign = index % 30
>         }

Besides what was allready said about hotspot and other optimizations
that might affect the benchmark. Also concider that you might
accidentally measure class loading if this for comprehension
introduces new classes after your "started" has been set.

And then there's the cosmic flux to consider....

I am teh burnout ;)
 


BR,
John



--
Viktor Klang
Senior Systems Analyst

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland