<div dir="ltr">I see that TR's type->contract returns <br><br> (-> (flat-named-contract (quote Float) flonum?) (flat-named-contract (quote Float) flonum?))<br><br>for the type (Float -> Float), but it could return<div>
<br></div><div> (-> (flat-named-contract (quote Float) flonum?) any)<br><br>which wouldn't do any result value checking (this being different from any/c as the range of the arrow contract).</div><div><br></div><div>
Robby<br><br>On Wed, Dec 11, 2013 at 6:18 PM, Neil Toronto <<a href="mailto:neil.toronto@gmail.com">neil.toronto@gmail.com</a>> wrote:<br>><br>> On 12/11/2013 02:49 PM, Neil Toronto wrote:<br>>><br>>> On 12/11/2013 01:55 PM, Stephen Bloch wrote:<br>
>>>><br>>>>> On Dec 11, 2013, at 2:36 PM, Neil Toronto wrote:<br>>>>><br>>>>>> numeric primitives implemented in Typed Racket are faster than the<br>>>>>> same primitives implemented in C.<br>
>>><br>>>><br>>>> Whoa!  How did that happen?<br>>><br>>><br>>> Whoa! That's not what I meant! O_o<br>>><br>>> I said "we might be getting close" to that. I haven't tried porting a<br>
>> numeric C primitive to TR yet, but I have a hunch that it'll still be<br>>> slower. I'll try one now and report what I find.<br>>><br>>> Neil ⊥<br>><br>><br>> 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.<br>
><br>> 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.<br>
><br>><br>> Function         Flonum  Rational  Fixnum  Integer  Float-Complex<br>> -------------------------------------------------------------------<br>> magnitude*         385      419      378     414         686<br>
> magnitude           59       44       40      40         390<br>><br>><br>> 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.<br>
><br>> I'll bet checking the return value contract (which is unnecessary) is the main slowdown. It has to check for number of values.<br>><br>> For comparison, here are the timings for running the benchmarks in TR with #:no-optimize:<br>
><br>><br>> Function         Flonum  Rational  Fixnum  Integer  Float-Complex<br>> -------------------------------------------------------------------<br>> magnitude*          45       70*      37     102*       318<br>
> magnitude           61       45       39      91*       394<br>><br>>                                               * = unexpectedly high<br>><br>><br>> Here's what I understand from comparing the numbers:<br>
><br>>  * 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.<br>><br>>  * Calling `abs' in Racket is faster than calling `scheme_abs' in C, except on rationals and big integers.<br>
><br>>  * Operating on flonums in Typed Racket, using generic numeric functions, is faster than doing the same in C.<br>><br>> 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.<br>
><br>> (I managed to make a `magnitude*' with type Number -> AnyValues, but TR couldn't make a contract for it.)<br>><br>> Neil ⊥<br>><br>><br>> _________________________<br>>   Racket Developers list:<br>
>   <a href="http://lists.racket-lang.org/dev">http://lists.racket-lang.org/dev</a><br>><br></div></div>