[racket] Performance. Higher-order function

From: Gustavo Massaccesi (gustavo at oma.org.ar)
Date: Tue Aug 5 10:44:12 EDT 2014

I made another test, using begin-encourage-inlining. I copied the
definition of build-string and compare the "normal" version with the
"inlined" version in Racket 6.1

"racket" version:
cpu time: 1326 real time: 1334 gc time: 78
cpu time: 1248 real time: 1262 gc time: 31
cpu time: 1264 real time: 1264 gc time: 15

"normal" version:
cpu time: 1248 real time: 1250 gc time: 16
cpu time: 1263 real time: 1282 gc time: 31
cpu time: 1264 real time: 1250 gc time: 15

"inlined" version:
cpu time: 546 real time: 570 gc time: 16
cpu time: 546 real time: 582 gc time: 0
cpu time: 562 real time: 550 gc time: 16

The fist two versions have almost the same time, as expected because
it's a copy. The last version is much faster.

The functions build-vector, build-string and build-list look like good
candidates for begin-encourage-inlining. They are too long for the
automatic inlining heuristic, but they are not very long. They also
use an argument as a function, so knowing the function and perhaps
inlining it can make some further improvement.

Additionally, the function checks the type of the arguments. But if I
remove the checks, the time almost doesn't change. These checks are
fast.

Gustavo

;--- test.rkt ---
#lang racket/base
(require "build-string.rkt")
(define (test2 n)
    (build-string n integer->char))
(define (test4 n)
    (build-string-normal n integer->char))
(define (test5 n)
    (build-string-inline n integer->char))

(time (for ([i 100000]) (test2 100)))
(time (for ([i 100000]) (test2 100)))
(time (for ([i 100000]) (test2 100)))
(newline)
(time (for ([i 100000]) (test4 100)))
(time (for ([i 100000]) (test4 100)))
(time (for ([i 100000]) (test4 100)))
(newline)
(time (for ([i 100000]) (test5 100)))
(time (for ([i 100000]) (test5 100)))
(time (for ([i 100000]) (test5 100)))
;------

;-- build-string.rkt ---
#lang racket/base
(require racket/performance-hint)
(provide (all-defined-out))

(define (build-string-normal n fcn)
  (unless (exact-nonnegative-integer? n)
    (raise-argument-error 'build-string "exact-nonnegative-integer?" n))
  (unless (and (procedure? fcn)
               (procedure-arity-includes? fcn 1))
    (raise-argument-error 'build-string "(exact-nonnegative-integer? .
-> . char?)" fcn))
  (let ([str (make-string n)])
    (let loop ((i 0))
      (if (= i n)
        str
        (begin (string-set! str i (fcn i)) (loop (add1 i)))))))

(begin-encourage-inline
  (define (build-string-inline n fcn)
    (unless (exact-nonnegative-integer? n)
      (raise-argument-error 'build-string "exact-nonnegative-integer?" n))
    (unless (and (procedure? fcn)
                 (procedure-arity-includes? fcn 1))
      (raise-argument-error 'build-string "(exact-nonnegative-integer?
. -> . char?)" fcn))
    (let ([str (make-string n)])
      (let loop ((i 0))
        (if (= i n)
          str
          (begin (string-set! str i (fcn i)) (loop (add1 i)))))))
   )
; ------



On Mon, Aug 4, 2014 at 12:42 AM, Roman Klochkov <kalimehtar at mail.ru> wrote:
>> unknown function call is expensive
>
> So, higher order function always slow.
> Thus, to improve performance, one should use for/fold, for/list, ... and
> never use map, foldl, build-string, ... with lambda.
> Is it correct?
>
> Sun, 3 Aug 2014 13:15:57 -0400 от Matthias Felleisen <matthias at ccs.neu.edu>:
>
>
> Because build-string calls an unknown function 1000 x 100000 times, and an
> unknown function call is expensive.
>
> Racket could possible collapse all modules and perform additional in-lining
> optimizations eventually, which may help here. But it doesn't yet.
>
> -- Matthias
>
>
>
> On Aug 3, 2014, at 5:15 AM, Roman Klochkov wrote:
>
> Are higher order function always slow?
> ...
>
> ---
>
> So I see, that build-string version is about two times slower, than
> set-in-the-loop. Why so much? I expected about 10-20% difference.
>
> --
> Roman Klochkov
> ____________________
>  Racket Users list:
>  http://lists.racket-lang.org/users
>
>
>
>
> --
> Roman Klochkov
>
> ____________________
>   Racket Users list:
>   http://lists.racket-lang.org/users
>


Posted on the users mailing list.