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

@specializing Scala Function2

23 replies
ichoran
Joined: 2009-08-14,
User offline. Last seen 2 years 3 weeks ago.
As a user of Scala for high-performance computing (in the colloquial sense; I do not run massive parallel computations on huge clusters), I am especially interested in @specialized.  The few tests I've run on it look very promising.  But there is one huge drawback right now: the library is implemented without use of @specialized.

I have been thinking about what would be required to make the library perform as impressively as one would hope, in order to minimize the writing of awkward boilerplate.

The first and most important specialization is for Function.  This is the workhorse of the entire collections library and the functional paradigm, and right now it is essentially useless for high-performance code that uses primitives because it has to wrap the primitives.  Granted, I normally try to use something higher level (e.g. vectors) when I can, but it really knocks the wind out of the functional paradigm when one has to jump back to
  var j = 0
  while (j<n) { j+=1 ; /* code */ }
so often.

Unfortunately, although a majority of use cases are for Function0 and Function1, some very important cases use Function2: fold and reduce, for example.  There is no particular reason why
  (0 /: intArray)((sum,i) => sum + i)
has to be any slower than
  object Adder { def add(i: Int,j: Int) = i+j }
  var sum = 0
  var i = 0
  while (i < intArray.length) {
    sum = Adder.add( sum , intArray(i) )
    i += 1
  }
  sum
As it stands now, the simple case above takes 0.4 ns per iteration on my test machine, while the fold takes 18 ns.  A 45x slowdown is pretty unfriendly.  (If you make this a little more complex so the JVM can't throw out the function call entirely, the lower case adds 0.4 ns or so to whatever operation you're doing, while the fold adds 18 ns or so; if not a full 45x slowdown in the operation, it's a 45x addition to the overhead.)

The problem, of course, is that if you @specialize all three arguments of Function2 over all nine primitives, you suddenly have 729 different apply methods.  Ouch.

But if we look more closely, we don't actually have three independent types.  We really only have two, for a majority of the cases:
  A + B => A
  A + B => B
  A + A => B
If we could speed these three up, almost everything written naively would be blazingly fast (i.e. "as fast as it ought to be").  Yes, it's still 243 methods, but they're very small methods.

So I have a proposal: the library should, one way or another, @specialize Function2 for these degenerate cases: either by allowing specialization of linked types cleverly when the type signature allows anything, or by creating Function2LeftTyped, Function2RightTyped and Function2SameTyped classes that were used by folds in preference to Function2, and where the => shorthand would use one of those instead of Function2 when possible.  (The latter is a little messy because one would then need implicit conversions from correctly-typed Function2s into the special subtypes.)

Another issue is whether all nine types really need to be specialized.  The byte/short/int distinction is poorly maintained by Java anyway.

Anyway, what's the status of @specialized currently?  Is there a plan for what 2.8 will look like in that regard?

  --Rex
ijuma
Joined: 2008-08-20,
User offline. Last seen 22 weeks 2 days ago.
Re: @specializing Scala Function2

Rex Kerr gmail.com> writes:
> Anyway, what's the status of specialized currently?  Is there a plan for
what 2.8 will look like in that regard?  --Rex

See the following message and follow-ups:

http://article.gmane.org/gmane.comp.lang.scala.internals/3111

Best,
Ismael

Iulian Dragos 2
Joined: 2009-02-10,
User offline. Last seen 42 years 45 weeks ago.
Re: @specializing Scala Function2


On Fri, Mar 26, 2010 at 10:39 PM, Rex Kerr <ichoran [at] gmail [dot] com> wrote:
The problem, of course, is that if you @specialize all three arguments of Function2 over all nine primitives, you suddenly have 729 different apply methods.  Ouch.

Indeed. The plan is to turn specialization on by default and specialize functions, tuples (up to 2) and Range.foreach. To limit the number of classes, they will be specialized only on Int, Long, Double (and Unit for result tpes). They will land in trunk very soon now, but there are a few unrelated issues that keep this from happening. In time, we'll add more specialization to the library, a prime candidate being the Numeric hierarchy.
I like your idea about constraining the cartesian product, if we can find a good syntax this could be added in the future. For instance, we could allow Function2[@specialized +T1, @specialized("T1") +T2, @specialized("T1, T2") -R]. The problem with this is that we recently decided the argument to @specialized won't be string anymore (too flaky), but a repeated parameter of companion objects of primitive types: @specialized(Int, Double). This does not allow specifying a type parameter, we have to think of something else. Given the tight schedule for 2.8.0, something along these lines will have to wait the next release.  iulian

But if we look more closely, we don't actually have three independent types.  We really only have two, for a majority of the cases:
  A + B => A
  A + B => B
  A + A => B
If we could speed these three up, almost everything written naively would be blazingly fast (i.e. "as fast as it ought to be").  Yes, it's still 243 methods, but they're very small methods.

So I have a proposal: the library should, one way or another, @specialize Function2 for these degenerate cases: either by allowing specialization of linked types cleverly when the type signature allows anything, or by creating Function2LeftTyped, Function2RightTyped and Function2SameTyped classes that were used by folds in preference to Function2, and where the => shorthand would use one of those instead of Function2 when possible.  (The latter is a little messy because one would then need implicit conversions from correctly-typed Function2s into the special subtypes.)

Another issue is whether all nine types really need to be specialized.  The byte/short/int distinction is poorly maintained by Java anyway.

Anyway, what's the status of @specialized currently?  Is there a plan for what 2.8 will look like in that regard?

  --Rex



--
« Je déteste la montagne, ça cache le paysage »
Alphonse Allais
ichoran
Joined: 2009-08-14,
User offline. Last seen 2 years 3 weeks ago.
Re: @specializing Scala Function2
Thanks for the update, Iulian!

On Sun, Mar 28, 2010 at 4:39 AM, Iulian Dragos <iulian [dot] dragos [at] epfl [dot] ch> wrote:


On Fri, Mar 26, 2010 at 10:39 PM, Rex Kerr <ichoran [at] gmail [dot] com> wrote:
The problem, of course, is that if you @specialize all three arguments of Function2 over all nine primitives, you suddenly have 729 different apply methods.  Ouch.

Indeed. The plan is to turn specialization on by default and specialize functions, tuples (up to 2) and Range.foreach. To limit the number of classes, they will be specialized only on Int, Long, Double (and Unit for result tpes). They will land in trunk very soon now, but there are a few unrelated issues that keep this from happening. In time, we'll add more specialization to the library, a prime candidate being the Numeric hierarchy.

I hope collections aren't too far behind; being able to use them in a high-performance way is, to me, the main draw of specialization.  After all, I can without too much trouble write my own classes that contain an apply method (or "f", if I want fewer characters to type)--so it's great to get the short and convenient (t: T) => U syntax, but this saves me a modest amount of work compared to what would be saved if I could use foreach and map on ArrayBuffer (for instance) and have it look like I was iterating over primitive arrays.
 
I like your idea about constraining the cartesian product, if we can find a good syntax this could be added in the future. For instance, we could allow Function2[@specialized +T1, @specialized("T1") +T2, @specialized("T1, T2") -R]. The problem with this is that we recently decided the argument to @specialized won't be string anymore (too flaky), but a repeated parameter of companion objects of primitive types: @specialized(Int, Double).

If we just want to allow identity, how about something like
  class Example[@specialized(Int,Double) A, @specializedAs(A) B] { ... }

One could envision a completely general scheme, but I'm not sure one could ever get this compact enough (or believe that this was important enough) to want it:
  class Example[
    @specialized( Set(Int,Double) ) A,
    @specialized( Set(Boolean,Float) ) B ,
    @specialized( Map[(A,B),C](
      (Int,Boolean)->Int,
      (Int,Float)->Float,
      (Double,Boolean)->Double,
      (Double,Float)->Double
    ) ) C
  ] { ... }

(This would work best, I expect, as part of a general way to relate input types to output types; that in turn would probably require a much more intimate interaction with the type system than is currently present in the code.)

  --Rex
 
ijuma
Joined: 2008-08-20,
User offline. Last seen 22 weeks 2 days ago.
Re: @specializing Scala Function2

Hey Iulian,

Iulian Dragos epfl.ch> writes:
> Indeed. The plan is to turn specialization on by default and specialize
> functions, tuples (up to 2) and Range.foreach. To limit the number of classes,
> they will be specialized only on Int, Long, Double (and Unit for result tpes).

I agree that Int, Long and Double are the most important.

Having said that, what about functions that involve Byte? These are quite common
in I/O and it would be nice to avoid the indirection even if Byte instances are
cached.

Best,
Ismael

dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: Re: @specializing Scala Function2
Though true, at least I/O code is less often CPU-bound.

On Mon, Apr 5, 2010 at 12:39 PM, Ismael Juma <mlists [at] juma [dot] me [dot] uk> wrote:
Hey Iulian,

Iulian Dragos <iulian.dragos <at> epfl.ch> writes:
> Indeed. The plan is to turn specialization on by default and specialize
> functions, tuples (up to 2) and Range.foreach. To limit the number of classes,
> they will be specialized only on Int, Long, Double (and Unit for result tpes).

I agree that Int, Long and Double are the most important.

Having said that, what about functions that involve Byte? These are quite common
in I/O and it would be nice to avoid the indirection even if Byte instances are
cached.

Best,
Ismael




--
Daniel C. Sobral

I travel to the future all the time.
ijuma
Joined: 2008-08-20,
User offline. Last seen 22 weeks 2 days ago.
Re: @specializing Scala Function2

Daniel Sobral gmail.com> writes:
> Though true, at least I/O code is less often CPU-bound.

Yes, but I/O abstractions can often be used with memory-based structures too
(and performance often matters in those cases).

Best,
Ismael

ichoran
Joined: 2009-08-14,
User offline. Last seen 2 years 3 weeks ago.
Re: Re: @specializing Scala Function2
I wonder if it is it possible to wrap byte with int in this case, instead of wrapping byte with java.lang.Byte?
  --Rex


On Mon, Apr 5, 2010 at 1:29 PM, Ismael Juma <mlists [at] juma [dot] me [dot] uk> wrote:
Daniel Sobral <dcsobral <at> gmail.com> writes:
> Though true, at least I/O code is less often CPU-bound.

Yes, but I/O abstractions can often be used with memory-based structures too
(and performance often matters in those cases).

Best,
Ismael


Chris Marshall
Joined: 2009-06-17,
User offline. Last seen 44 weeks 3 days ago.
RE: Re: @specializing Scala Function2
Can we also have specialization on Boolean as a result-type, for predicate expressions?

> To: scala-debate [at] listes [dot] epfl [dot] ch
> Subject: [scala-debate] Re: @specializing Scala Function2
> Date: Mon, 5 Apr 2010 15:39:01 +0000
>
> I agree that Int, Long and Double are the most important.
 


Get a free e-mail account with Hotmail. Sign-up now.
Rüdiger Keller
Joined: 2010-01-24,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: @specializing Scala Function2

Hi,

I would really like to see Float included in the list of specialized
types. I am writing a lot of performance critical code and I neither
need the increased precision nor do I want to pay the memory and speed
overhead of Double.

As for specializing Boolean, that's probably the least important,
because there will never be more than two Boolean instances allocated
anyway and boxing should therefore be cheap. I guess.

As far as I remember, all integral types but Long are stored as 32 bit
integers on the stack. But as method signatures and opcodes discern
the various integral types (e.g. because of rounding behavior) I would
guess that it is not possible to omit the specializations for them and
reuse the Int-specialized methods instead.

Btw, what's the progress on specialization and the release candidate?

Cheers,
Ruediger

odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.
Re: Re: @specializing Scala Function2
If we grant all requests, I.e. specialize on Byte, Int, Long, Float, Double,
and in addition on Boolean and Unit in the result type, we get

5 * 5 * 7 = 175

methods in Function 2. So this means 175 methods in AbstractFuncton2, and in all other classes
that implement the Function2 trait, which are hopefully not many. I think that's still acceptable.

Question: Does it also make sense to specialize on mixed Object/primitive type combinations,
and can we specify that?

Cheers

 -- Martin


On Tue, Apr 6, 2010 at 7:00 PM, Rüdiger Keller <ruediger [dot] keller [at] googlemail [dot] com> wrote:
Hi,

I would really like to see Float included in the list of specialized
types. I am writing a lot of performance critical code and I neither
need the increased precision nor do I want to pay the memory and speed
overhead of Double.

As for specializing Boolean, that's probably the least important,
because there will never be more than two Boolean instances allocated
anyway and boxing should therefore be cheap. I guess.

As far as I remember, all integral types but Long are stored as 32 bit
integers on the stack. But as method signatures and opcodes discern
the various integral types (e.g. because of rounding behavior) I would
guess that it is not possible to omit the specializations for them and
reuse the Int-specialized methods instead.

Btw, what's the progress on specialization and the release candidate?

Cheers,
Ruediger

ichoran
Joined: 2009-08-14,
User offline. Last seen 2 years 3 weeks ago.
Re: Re: @specializing Scala Function2
On Tue, Apr 6, 2010 at 1:00 PM, Rüdiger Keller <ruediger [dot] keller [at] googlemail [dot] com> wrote:
Hi,

I would really like to see Float included in the list of specialized
types. I am writing a lot of performance critical code and I neither
need the increased precision nor do I want to pay the memory and speed
overhead of Double.

I'm in the same boat.  I like Float specialization also.
 
As far as I remember, all integral types but Long are stored as 32 bit
integers on the stack. But as method signatures and opcodes discern
the various integral types (e.g. because of rounding behavior) I would
guess that it is not possible to omit the specializations for them and
reuse the Int-specialized methods instead.

Mixing mathematics and comparisons (or right shifts) would cause problems; otherwise, you could do it safely.  One could make the compiler sufficiently savvy to understand when it was safe and when it wasn't (and throw an error if you tried to specialize byte-as-int in an unsafe context), but that sounds like a fair bit of work to me.  I do hope that eventually this work will get done.

  --Rex
 
dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: Re: @specializing Scala Function2
That depends on the degree of control. The most common use case will be [A, A, A] and [A, A, Boolean], for A in Byte, Int, Long, Float, Double. That's just 5 * 2 = 10.

On Tue, Apr 6, 2010 at 2:13 PM, martin odersky <martin [dot] odersky [at] epfl [dot] ch> wrote:
If we grant all requests, I.e. specialize on Byte, Int, Long, Float, Double,
and in addition on Boolean and Unit in the result type, we get

5 * 5 * 7 = 175

methods in Function 2. So this means 175 methods in AbstractFuncton2, and in all other classes
that implement the Function2 trait, which are hopefully not many. I think that's still acceptable.

Question: Does it also make sense to specialize on mixed Object/primitive type combinations,
and can we specify that?

Cheers

 -- Martin


On Tue, Apr 6, 2010 at 7:00 PM, Rüdiger Keller <ruediger [dot] keller [at] googlemail [dot] com> wrote:
Hi,

I would really like to see Float included in the list of specialized
types. I am writing a lot of performance critical code and I neither
need the increased precision nor do I want to pay the memory and speed
overhead of Double.

As for specializing Boolean, that's probably the least important,
because there will never be more than two Boolean instances allocated
anyway and boxing should therefore be cheap. I guess.

As far as I remember, all integral types but Long are stored as 32 bit
integers on the stack. But as method signatures and opcodes discern
the various integral types (e.g. because of rounding behavior) I would
guess that it is not possible to omit the specializations for them and
reuse the Int-specialized methods instead.

Btw, what's the progress on specialization and the release candidate?

Cheers,
Ruediger




--
Daniel C. Sobral

I travel to the future all the time.
odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.
Re: Re: @specializing Scala Function2


On Tue, Apr 6, 2010 at 7:19 PM, Daniel Sobral <dcsobral [at] gmail [dot] com> wrote:
That depends on the degree of control. The most common use case will be [A, A, A] and [A, A, Boolean], for A in Byte, Int, Long, Float, Double. That's just 5 * 2 = 10.
Yes,  but as far as I know we do not have a way to specify these combinations at present,

Cheers

 -- Martin


On Tue, Apr 6, 2010 at 2:13 PM, martin odersky <martin [dot] odersky [at] epfl [dot] ch> wrote:
If we grant all requests, I.e. specialize on Byte, Int, Long, Float, Double,
and in addition on Boolean and Unit in the result type, we get

5 * 5 * 7 = 175

methods in Function 2. So this means 175 methods in AbstractFuncton2, and in all other classes
that implement the Function2 trait, which are hopefully not many. I think that's still acceptable.

Question: Does it also make sense to specialize on mixed Object/primitive type combinations,
and can we specify that?

Cheers

 -- Martin


On Tue, Apr 6, 2010 at 7:00 PM, Rüdiger Keller <ruediger [dot] keller [at] googlemail [dot] com> wrote:
Hi,

I would really like to see Float included in the list of specialized
types. I am writing a lot of performance critical code and I neither
need the increased precision nor do I want to pay the memory and speed
overhead of Double.

As for specializing Boolean, that's probably the least important,
because there will never be more than two Boolean instances allocated
anyway and boxing should therefore be cheap. I guess.

As far as I remember, all integral types but Long are stored as 32 bit
integers on the stack. But as method signatures and opcodes discern
the various integral types (e.g. because of rounding behavior) I would
guess that it is not possible to omit the specializations for them and
reuse the Int-specialized methods instead.

Btw, what's the progress on specialization and the release candidate?

Cheers,
Ruediger




--
Daniel C. Sobral

I travel to the future all the time.

ichoran
Joined: 2009-08-14,
User offline. Last seen 2 years 3 weeks ago.
Re: Re: @specializing Scala Function2
I've done a bunch of testing to see where it makes sense to put in effort.  In each case, I've tested with an algorithm that looks approximately like

    var count = 0
    var i = 0
    while (i<1000000000) {
      i += 1
      count += f(i, i*3)
    }
    count

where f(a,b) = (a-1)*b.  (Boolean is the only exception.)

Generally, this operation takes ~2 s on my machine--or 2 ns/iteration.  (Int is more like 1, Long is more like 4.)  Then I tried using the existing Function2 to implement f, or a custom class with an apply of appropriate signature.  For types with a limited number of values (Short, Char), I tried pre-computing all possible values and using those instead of creating new ones for wrapping.

Here are the results (view fixed-width):

Calc:     Function2   Custom  Pre-allocated
          ---------   ------  -------------
Boolean     (0.2)       0.0      nd      <- Faster unspecialized!
Byte         1.6       (0.2)     2.0     <- Already preallocated?
Short       26.1       (0.2)     5.3
Char        27.4        0.0      4.7
Int         29.2        0.1      na
Long        23.7       (0.3)     na
Float       26.3        0.1      na
Double      26.3        0.1      na     
(all values in ns overhead / call ; values in parens are negative).

So, I think it's clear that Int, Long, Float, Double should all be specialized. Byte already only has a performance penalty of ~2x compared to raw access, so boxing should be fine; Boolean doesn't seem to benefit any from boxing or lack thereof!

The interesting cases are Short and Char.  These results show a very clear benefit for specializing on those types, _but_ they show an alternate strategy that gives ~5x improvement: when boxing, don't create a new object, but point at a pre-created one.  I suggest that this alternate be the normal strategy.  This is already what happens with Byte, apparently.

This suggests to me that appropriate specialization is (Int,Long,Float,Double).  I'm not sure (Byte, Short, Char) are worth it, especially with the alternate option of using a lookup table (think memoization, I suppose) for Short and Char.

I do think there is good reason to specialize with all mixings of the defaults as well (Object), but that still gives only 125 possibilities.

  --Rex

P.S. Test code available upon request.

On Tue, Apr 6, 2010 at 1:13 PM, martin odersky <martin [dot] odersky [at] epfl [dot] ch> wrote:
If we grant all requests, I.e. specialize on Byte, Int, Long, Float, Double,
and in addition on Boolean and Unit in the result type, we get

5 * 5 * 7 = 175

methods in Function 2. So this means 175 methods in AbstractFuncton2, and in all other classes
that implement the Function2 trait, which are hopefully not many. I think that's still acceptable.

Question: Does it also make sense to specialize on mixed Object/primitive type combinations,
and can we specify that?

Cheers

 -- Martin

jonathan mawson
Joined: 2010-01-28,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: @specializing Scala Function2

A lot of the discussion here seems bizarrely obsolete. What can people be
doing that truly requires high performance Byte maths?? Writing 8 bit
texture mappers? I think not! Ditto for Int.

Even Float and Double don't seem that important - anyone who really needs
fast maths performance for science of finance will use CUDA, surely? I'd
suggest on concentrating on Float and Double at most, and even considering
not covering Float * Double. Keep it simple, and get on with the important
stuff instead.

Kevin Wright
Joined: 2009-06-09,
User offline. Last seen 49 weeks 3 days ago.
Re: Re: @specializing Scala Function2
Plenty of protocol handling and networky stuff will benefit from high-performance byte maths, so I wouldn't be too quick to rule it out...


On 6 April 2010 23:50, jonathan mawson <umptious [at] gmail [dot] com> wrote:

A lot of the discussion here seems bizarrely obsolete. What can people be
doing that truly requires high performance Byte maths?? Writing 8 bit
texture mappers? I think not! Ditto for Int.

Even Float and Double don't seem that important - anyone who really needs
fast maths performance for science of finance will use CUDA, surely? I'd
suggest on concentrating on Float and Double at most, and even considering
not covering Float * Double. Keep it simple, and get on with the important
stuff instead.

--
View this message in context: http://old.nabble.com/%40specializing-Scala-Function2-tp28048228p28158561.html
Sent from the Scala - Debate mailing list archive at Nabble.com.




--
Kevin Wright

mail/google talk: kev [dot] lee [dot] wright [at] googlemail [dot] com
wave: kev [dot] lee [dot] wright [at] googlewave [dot] com
skype: kev.lee.wright
twitter: @thecoda

Rüdiger Keller
Joined: 2010-01-24,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: @specializing Scala Function2

Only because you do not have an application for @specialize does not
mean that nobody does. You will think differently about this if you
encounter these performance constraints yourself.

Greetings,
Ruediger

2010/4/7 jonathan mawson :
>
> A lot of the discussion here seems bizarrely obsolete. What can people be
> doing that truly requires high performance Byte maths?? Writing 8 bit
> texture mappers? I think not! Ditto for Int.
>
> Even Float and Double don't seem that important - anyone who really needs
> fast maths performance for science of finance will use CUDA, surely? I'd
> suggest on concentrating on Float and Double at most, and even considering
> not covering Float * Double. Keep it simple, and get on with the important
> stuff instead.
>
> --
> View this message in context: http://old.nabble.com/%40specializing-Scala-Function2-tp28048228p2815856...
> Sent from the Scala - Debate mailing list archive at Nabble.com.
>
>

ichoran
Joined: 2009-08-14,
User offline. Last seen 2 years 3 weeks ago.
Re: Re: @specializing Scala Function2
On Tue, Apr 6, 2010 at 6:50 PM, jonathan mawson <umptious [at] gmail [dot] com> wrote:

A lot of the discussion here seems bizarrely obsolete. What can people be
doing that truly requires high performance Byte maths??

Sometimes you need to interact with files at a low level, which usually means bytes.  You might want to x.find(_==(some value)), or y.map(lookup(_)), or whatnot.
 

Even Float and Double don't seem that important - anyone who really needs
fast maths performance for science of finance will use CUDA, surely?

No.  CUDA is not broadly portable, is restricted to hardware that is not universal, and accelerates operations that are only a subset of what one might want to use in finance or scientific computing.  For certain applications it's worth the effort to CUDAize it (including buying hardware as necessary).  For most, it's not.

  --Rex

dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: Re: @specializing Scala Function2
Nonsense. I can only assume you have no performance problems at all, because almost any application that hasn't been rewritten to get rid of functions will benefit from this. Generally speaking, if you use for comprehensions, if you use map, flatMap or filter, you'll see gains. If you have multiple generators inside the for comprehension, you'll see _big_ gains. Unless you don't use any primitive types at all.

On Tue, Apr 6, 2010 at 7:50 PM, jonathan mawson <umptious [at] gmail [dot] com> wrote:

A lot of the discussion here seems bizarrely obsolete. What can people be
doing that truly requires high performance Byte maths?? Writing 8 bit
texture mappers? I think not! Ditto for Int.

Even Float and Double don't seem that important - anyone who really needs
fast maths performance for science of finance will use CUDA, surely? I'd
suggest on concentrating on Float and Double at most, and even considering
not covering Float * Double. Keep it simple, and get on with the important
stuff instead.

--
View this message in context: http://old.nabble.com/%40specializing-Scala-Function2-tp28048228p28158561.html
Sent from the Scala - Debate mailing list archive at Nabble.com.




--
Daniel C. Sobral

I travel to the future all the time.
Grey
Joined: 2009-01-03,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: @specializing Scala Function2
Not a lot of thought on this but .. 
MLton is a whole program optimizing compiler which generates tagless monomorphic code for primitives, sort of kinda what @specialize does.  One ramification of MLton is it recompiles _everything_  everytime including the standard basis library etc. as well as user code.  In this view the standard library source is no more distinguished than the application code.
SBT is pretty darn smart on compiling only what needs to be compiled and no more and the Scala compiler isn't that slow. :)
The thought is ...
  a) To not pre-compile all of the Scala library and explicitly leaving keys files, Function2 et al, as source files.   The compiler could have some special knowledge of the standard library such as library source file location, auto add them into the compilation path etc.
  b) The Scala compiler via the omniscient whole program analysis plugin (still on track for 2.8 correct?) notes what specializations are required and generates only the required monomorphic methods in the class.
On Tue, Apr 6, 2010 at 1:13 PM, martin odersky <martin [dot] odersky [at] epfl [dot] ch> wrote:
If we grant all requests, I.e. specialize on Byte, Int, Long, Float, Double,
and in addition on Boolean and Unit in the result type, we get

5 * 5 * 7 = 175

methods in Function 2. So this means 175 methods in AbstractFuncton2, and in all other classes
that implement the Function2 trait, which are hopefully not many. I think that's still acceptable.

Question: Does it also make sense to specialize on mixed Object/primitive type combinations,
and can we specify that?

Cheers

 -- Martin


On Tue, Apr 6, 2010 at 7:00 PM, Rüdiger Keller <ruediger [dot] keller [at] googlemail [dot] com> wrote:
Hi,

I would really like to see Float included in the list of specialized
types. I am writing a lot of performance critical code and I neither
need the increased precision nor do I want to pay the memory and speed
overhead of Double.

As for specializing Boolean, that's probably the least important,
because there will never be more than two Boolean instances allocated
anyway and boxing should therefore be cheap. I guess.

As far as I remember, all integral types but Long are stored as 32 bit
integers on the stack. But as method signatures and opcodes discern
the various integral types (e.g. because of rounding behavior) I would
guess that it is not possible to omit the specializations for them and
reuse the Int-specialized methods instead.

Btw, what's the progress on specialization and the release candidate?

Cheers,
Ruediger




--
The object of life is not to be on the side of the majority, but to escape finding oneself in the ranks of the insane. - Marcus Aurelius
ichoran
Joined: 2009-08-14,
User offline. Last seen 2 years 3 weeks ago.
Re: Re: @specializing Scala Function2
On Tue, Apr 6, 2010 at 10:17 PM, Ray Racine <ray [dot] racine [at] gmail [dot] com> wrote:

  a) To not pre-compile all of the Scala library and explicitly leaving keys files, Function2 et al, as source files.

Can we say "C++ templates"?

This does have the unfortunate effect of needing everything templated available as source.

  --Rex

Johannes Rudolph 2
Joined: 2010-02-12,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: @specializing Scala Function2

Since there are no shorter types than int in the JVM anyways could you
can just use the specialized int variants for those cases. See this
Java example:

class Test {
  public static byte test(byte c) {
    return (byte)(c + 1);
  }
  public static int testI(int x) {
    return (byte)(x + 1);
  }
  public static void main(String[] args) {
    byte c = 15;
    byte c2 = test(c);
    byte c3 = (byte)testI(c);
    System.out.println("c2: "+c2+" c3:"+c3);
  }
}

The test method is implemented twice, once as a byte method, once as
an int method. In Java an explicit cast to byte is needed in any case.
Here are the relevant bytecodes:

public static byte test(byte);
Code:
0: iload_0
1: iconst_1
2: iadd
3: i2b
4: ireturn

public static int testI(int);
Code:
0: iload_0
1: iconst_1
2: iadd
3: i2b
4: ireturn

public static void main(java.lang.String[]);
Code:
0: bipush 15
2: istore_1
3: iload_1
4: invokestatic #2; //Method test:(B)B
7: istore_2
8: iload_1
9: invokestatic #3; //Method testI:(I)I
12: i2b
13: istore_3

As you can see the implementation is exactly the same regardless what
the exact signature of the methods is. The i2b instruction is a Java
bytecode int => int instruction which does the narrowing of the type.
In Scala where we know it is a byte-method in advance you could remove
the i2b instruction in main:12, as well, since it is known this was
done before.

So there's no need to specialize boolean, byte, short and char because
they actually are represented as ints internally anyway.

Am I missing anything?

Johannes

07.04.2010 05:52 schrieb am "Rex Kerr" :

On Tue, Apr 6, 2010 at 10:17 PM, Ray Racine wrote:
>
>
>   a) To not pre-comp...

Can we say "C++ templates"?

This does have the unfortunate effect of needing everything templated
available as source.

  --Rex

David Flemström
Joined: 2009-08-10,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: @specializing Scala Function2
On Wed, Apr 7, 2010 at 7:51 AM, Johannes Rudolph <johannes [dot] rudolph [at] googlemail [dot] com> wrote:
Am I missing anything?
 Correct handling of overflow. But code that relies on overflow is broken anyways so it's not too big of an issue.

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