[racket-dev] [plt] Push #27909: master branch updated

From: Neil Toronto (neil.toronto at gmail.com)
Date: Tue Jan 14 13:37:38 EST 2014

I don't think so. The flonum functions are Flonum -> Flonum, and 
`magnitude*' is Number -> Number.

The best candidate from the math library is probably `mean'.

Neil ⊥

On 01/14/2014 11:24 AM, Robby Findler wrote:
> Do any of these functions turn out to have case-> contracts by the time
> TR gets done with them?
>
> Robby
>
>
>
> On Tue, Jan 14, 2014 at 12:22 PM, Neil Toronto <neil.toronto at gmail.com
> <mailto:neil.toronto at gmail.com>> wrote:
>
>     An update on my math-centered tests. The first is the built-in
>     `magnitude' vs. a TR near-transliteration of its C implementation,
>     called from *untyped* Racket. The numbers are in milliseconds, for 5
>     million calls, by input type:
>
>
>     Function         Flonum  Rational  Fixnum  Integer  Float-Complex
>     ------------------------------__------------------------------__-------
>     Pre-static contracts:
>
>     magnitude*         385      419      378     414         686
>     magnitude           59       44       40      40         390
>     Post-static contracts:
>     magnitude*         175      196      164     195         475
>     magnitude           68       43       36      40         406
>
>     All but the Float-Complex case just return the absolute value of the
>     argument, so there's not much computation. They're dominated by
>     contract checking, and the speedup is 0.45 to 0.5. Nice. The
>     Float-Complex case does something substantive, and is close to C.
>     That's awesome.
>
>     So for really small functions (i.e. just a test and a call to
>     `abs'), writing them in C is still better. But for anything much
>     larger (that part of `magnitude*' is about 10 lines and 7-13 numeric
>     ops), a TR implementation isn't much slower than C (about 17%).
>
>     --
>
>     1 million iterations of some math library flonum functions, in TR,
>     untyped before Robby's changes, untyped after Robby's 12/12 changes,
>     and untyped after Eric's static contract changes, in milliseconds:
>
>     Function         TR     Untyped    Robby's   Robby's+Eric's
>     ------------------------------__------------------------------__--
>     flrational?       5       322        98           37
>     flsinh           55       343       121           86
>     fllog1p          47       351       117           80
>     lg+              61       384       154          115
>     flgamma         165       521       262          234
>
>     So calling TR floating-point functions from untyped Racket takes
>     only 0.11 to 0.45 times the amount of time it took only a month ago,
>     with typical cases being about 0.25. That's awesome.
>
>     Neil ⊥
>
>
>     On 01/14/2014 10:27 AM, Eric Dobson wrote:
>
>         The changes to TR contract generation are now in at HEAD.
>
>         If you can find any cases where contracts are still slowing programs
>         down by a lot I'd like to take a look at them. (Excepting the
>         case of
>         structs where I know it is still an issue).
>
>         On Thu, Dec 12, 2013 at 10:52 AM, Robby Findler
>         <robby at eecs.northwestern.edu
>         <mailto:robby at eecs.northwestern.edu>> wrote:
>
>             Re-reading your message I see that you're not actually
>             asserting something
>             different from what I said, but just for some precision here
>             I wish to point
>             out that I wasn't basing my opinion on intuition from the
>             code, but on some
>             microbenchmark timings. (There was a much more substantial
>             difference
>             yesterday because the loop inside any-wrap/c wasn't as cheap
>             as it could
>             have been.)
>
>             I'd be interested to see if your improvements to
>             type->contract improve the
>             situation any! I expect they will make things better again
>             for the Number
>             case, but at the moment, there isn't a big difference.
>
>             Program 1:
>
>
>             #lang racket/base
>             (module m typed/racket/base
>                 (: f (Any -> Any))
>                 (define (f x) 1)
>                 (provide f))
>             (require 'm)
>             (time
>                (for ([x (in-range 20000)])
>                  (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7)
>                  (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7)
>                  (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7)
>                  (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7)
>                  (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7)
>                  (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7)
>                  (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7)
>                  (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7)))
>
>             Timings:
>
>             cpu time: 142 real time: 142 gc time: 8
>             cpu time: 144 real time: 144 gc time: 7
>             cpu time: 144 real time: 143 gc time: 6
>             cpu time: 142 real time: 142 gc time: 6
>             cpu time: 142 real time: 142 gc time: 7
>             cpu time: 146 real time: 146 gc time: 6
>
>             Program 2:
>
>
>             #lang racket/base
>             (module m typed/racket/base
>                 (: f (Any -> Integer))
>
>                 (define (f x) 1)
>                 (provide f))
>             (require 'm)
>             (time
>                (for ([x (in-range 20000)])
>                  (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7)
>                  (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7)
>                  (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7)
>                  (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7)
>                  (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7)
>                  (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7)
>                  (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7)
>                  (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7)))
>
>
>             Timings:
>
>             cpu time: 139 real time: 138 gc time: 7
>             cpu time: 145 real time: 144 gc time: 7
>             cpu time: 140 real time: 140 gc time: 6
>             cpu time: 151 real time: 150 gc time: 6
>             cpu time: 139 real time: 138 gc time: 6
>             cpu time: 139 real time: 139 gc time: 8
>
>
>
>
>
>
>
>
>             On Thu, Dec 12, 2013 at 12:33 PM, Eric Dobson
>             <eric.n.dobson at gmail.com <mailto:eric.n.dobson at gmail.com>>
>             wrote:
>
>
>                 any-wrap/c still requires the check for one value, while
>                 any (which is
>                 from Number not Any) does not. So I would still guess at
>                 Number being
>                 faster, but Robby's changes may make it so that inlining
>                 and dead code
>                 elimination can see through everything and turn it into
>                 the same code.
>
>                 On Thu, Dec 12, 2013 at 10:27 AM, Robby Findler
>                 <robby at eecs.northwestern.edu
>                 <mailto:robby at eecs.northwestern.edu>> wrote:
>
>                     FWIW, my push speeds up the any-wrap/c
>                     implementation a bunch. Those two
>                     should have similar speeds after you get that, I guess.
>
>                     Robby
>
>
>                     On Thu, Dec 12, 2013 at 11:03 AM, Neil Toronto
>                     <neil.toronto at gmail.com <mailto:neil.toronto at gmail.com>>
>                     wrote:
>
>
>                         I tried your branch that implements it and saw
>                         about 3.5x speedup for
>                         the
>                         `magnitude*' test. This is of course without
>                         Robby's recent first-order
>                         contract changes.
>
>                         (I think it's about 3.5x: I tried with
>                         magnitude* : Number -> Any first
>                         and got 2400ms on the easy tests. I changed it
>                         to magnitude* : Number
>                         ->
>                         Number and got 690ms. Apparently, for an `Any'
>                         return type, an
>                         `any-wrap/c'
>                         contract is generated instead of nothing. If
>                         that's much faster to
>                         check
>                         than `number?', though, the speedup is even better.)
>
>                         I'd love to see this with Robby's recent
>                         changes. Hint? Nudge? Please?
>
>                         I didn't see very much speedup with arrays
>                         (about 1.2x). Speed tests on
>                         the math library's distribution objects were
>                         very interesting, though,
>                         and
>                         indicate why the arrays might not be much
>                         faster. Here's my test
>                         program:
>
>
>                         #lang racket
>
>                         (require math/distributions)
>
>                         (define d (normal-dist 0 1))
>
>                         (printf "pdf d 0~n")
>                         (for ([_  (in-range 5)])
>                             (time (for ([_  (in-range 100000)])
>                                     (pdf d 0))))
>                         (newline)
>
>                         (define p (distribution-pdf d))
>                         (printf "p 0~n")
>                         (for ([_  (in-range 5)])
>                             (time (for ([_  (in-range 100000)])
>                                     (p 0))))
>                         (newline)
>
>
>                         The two tests are equivalent, as `pdf' just
>                         pulls the pdf function out
>                         of
>                         the distribution struct and applies it. In TR,
>                         the tests are exactly
>                         the
>                         same speed (extremely fast). In untyped Racket,
>                         on the main branch, the
>                         second test is 16x faster, and on your branch,
>                         it's 44x faster. (It's
>                         still
>                         10x slower than TR on your branch, so again...
>                         I'd love to see your
>                         changes
>                         and Robby's together. :D)
>
>                         Neil ⊥
>
>
>                         On 12/12/2013 12:40 AM, Eric Dobson wrote:
>
>
>                             Removing the return value checking is in the
>                             works. It actually is
>                             removing all of the checks that would blame
>                             typed code, so higher
>                             order functions/datastructure get
>                             improvements too. It is actually
>                             functional the last time I checked, but
>                             lacking documentation which is
>                             what is holding up merging with mainline.
>
>                             https://github.com/plt/racket/__pull/453
>                             <https://github.com/plt/racket/pull/453>
>
>                             On Wed, Dec 11, 2013 at 7:57 PM, Robby Findler
>                             <robby at eecs.northwestern.edu
>                             <mailto:robby at eecs.northwestern.edu>> wrote:
>
>
>                                 I see that TR's type->contract returns
>
>                                     (-> (flat-named-contract (quote
>                                 Float) flonum?)
>                                 (flat-named-contract
>                                 (quote
>                                 Float) flonum?))
>
>                                 for the type (Float -> Float), but it
>                                 could return
>
>                                     (-> (flat-named-contract (quote
>                                 Float) flonum?) any)
>
>                                 which wouldn't do any result value
>                                 checking (this being different
>                                 from
>                                 any/c
>                                 as the range of the arrow contract).
>
>                                 Robby
>
>
>                                 On Wed, Dec 11, 2013 at 6:18 PM, Neil
>                                 Toronto
>                                 <neil.toronto at gmail.com
>                                 <mailto:neil.toronto at gmail.com>>
>                                 wrote:
>
>
>
>                                     On 12/11/2013 02:49 PM, Neil Toronto
>                                     wrote:
>
>
>
>                                         On 12/11/2013 01:55 PM, Stephen
>                                         Bloch wrote:
>
>
>
>                                                 On Dec 11, 2013, at 2:36
>                                                 PM, Neil Toronto wrote:
>
>                                                     numeric primitives
>                                                     implemented in Typed
>                                                     Racket are faster than
>                                                     the
>                                                     same primitives
>                                                     implemented in C.
>
>
>
>
>                                             Whoa!  How did that happen?
>
>
>
>
>                                         Whoa! That's not what I meant! O_o
>
>                                         I said "we might be getting
>                                         close" to that. I haven't tried
>                                         porting
>                                         a
>                                         numeric C primitive to TR yet,
>                                         but I have a hunch that it'll still
>                                         be
>                                         slower. I'll try one now and
>                                         report what I find.
>
>                                         Neil ⊥
>
>
>
>
>                                     I can't figure out why `flsinh' is
>                                     faster to call from untyped
>                                     Racket
>                                     than
>                                     `sinh'. All my tests with a Typed
>                                     Racket `magnitude' show calls from
>                                     untyped
>                                     code are significantly slower,
>                                     except in the one case that it
>                                     computes
>                                     Euclidean distance. That case is
>                                     only twice as slow.
>
>                                     I've attached the benchmark program.
>                                     The `magnitude*' function is
>                                     more
>                                     or
>                                     less a direct translation of
>                                     `magnitude' from "number.c" into Typed
>                                     Racket.
>                                     Here's a summary of the results I
>                                     get on my computer, in
>                                     milliseconds,
>                                     for 5
>                                     million calls from untyped Racket,
>                                     by data type.
>
>
>                                     Function         Flonum  Rational
>                                       Fixnum  Integer  Float-Complex
>                                     ------------------------------__------------------------------__-------
>                                     magnitude*         385      419
>                                       378     414         686
>                                     magnitude           59       44
>                                        40      40         390
>
>
>                                     The only one that's close in
>                                     relative terms is Float-Complex. The
>                                     others
>                                     just call `abs'. The decompiled code
>                                     doesn't show any inlining of
>                                     `magnitude', so this comparison
>                                     should be good.
>
>                                     I'll bet checking the return value
>                                     contract (which is unnecessary)
>                                     is
>                                     the
>                                     main slowdown. It has to check for
>                                     number of values.
>
>                                     For comparison, here are the timings
>                                     for running the benchmarks in
>                                     TR
>                                     with
>                                     #:no-optimize:
>
>
>                                     Function         Flonum  Rational
>                                       Fixnum  Integer  Float-Complex
>                                     ------------------------------__------------------------------__-------
>                                     magnitude*          45       70*
>                                       37     102*       318
>                                     magnitude           61       45
>                                        39      91*       394
>
>
>                                                  * = unexpectedly high
>
>
>                                     Here's what I understand from
>                                     comparing the numbers:
>
>                                         * Except for non-fixnum
>                                     integers, calling `magnitude' in TR is
>                                     just
>                                     as
>                                     fast as in untyped Racket. I have no
>                                     idea why it would be slower on
>                                     big
>                                     integers. That's just weird.
>
>                                         * Calling `abs' in Racket is
>                                     faster than calling `scheme_abs' in
>                                     C,
>                                     except on rationals and big integers.
>
>                                         * Operating on flonums in Typed
>                                     Racket, using generic numeric
>                                     functions,
>                                     is faster than doing the same in C.
>
>                                     Overall, it looks like the TR code
>                                     is within the same order of
>                                     magnitude
>                                     (pun not intended) as the C code. I
>                                     would love to try this benchmark
>                                     with
>                                     either 1) a `magnitude*' with an
>                                     `AnyValues' return type; or 2) a
>                                     contract
>                                     boundary that doesn't check TR's
>                                     return types for first-order
>                                     functions.
>
>                                     (I managed to make a `magnitude*'
>                                     with type Number -> AnyValues, but
>                                     TR
>                                     couldn't make a contract for it.)
>
>                                     Neil ⊥
>
>
>                                     _________________________
>                                          Racket Developers list:
>                                     http://lists.racket-lang.org/__dev
>                                     <http://lists.racket-lang.org/dev>
>
>
>                                 _________________________
>                                      Racket Developers list:
>                                 http://lists.racket-lang.org/__dev
>                                 <http://lists.racket-lang.org/dev>
>
>
>
>
>


Posted on the dev mailing list.