add racket/performance-hint' with
begin-encourage-inline'
This commit is contained in:
parent
1bc2441b5a
commit
545b37ff0d
|
@ -24,7 +24,8 @@ v4 todo:
|
||||||
"prop.rkt"
|
"prop.rkt"
|
||||||
"misc.rkt"
|
"misc.rkt"
|
||||||
"generate.rkt"
|
"generate.rkt"
|
||||||
racket/stxparam)
|
racket/stxparam
|
||||||
|
racket/performance-hint)
|
||||||
(require (for-syntax racket/base)
|
(require (for-syntax racket/base)
|
||||||
(for-syntax "helpers.rkt")
|
(for-syntax "helpers.rkt")
|
||||||
(for-syntax syntax/stx)
|
(for-syntax syntax/stx)
|
||||||
|
@ -74,14 +75,7 @@ v4 todo:
|
||||||
#,(call-gen #'())]
|
#,(call-gen #'())]
|
||||||
[else #,(call-gen rng-checkers)]))))
|
[else #,(call-gen rng-checkers)]))))
|
||||||
|
|
||||||
(define-syntax (cross-module-inline stx)
|
(begin-encourage-inline
|
||||||
(syntax-case stx ()
|
|
||||||
[(_ defn)
|
|
||||||
(syntax-property #'defn
|
|
||||||
'compiler-hint:cross-module-inline
|
|
||||||
#t)]))
|
|
||||||
|
|
||||||
(cross-module-inline
|
|
||||||
(define tail-marks-match?
|
(define tail-marks-match?
|
||||||
(case-lambda
|
(case-lambda
|
||||||
[(m) (and m (null? m))]
|
[(m) (and m (null? m))]
|
||||||
|
|
24
collects/racket/performance-hint.rkt
Normal file
24
collects/racket/performance-hint.rkt
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
|
||||||
|
(module inline '#%kernel
|
||||||
|
(#%require (for-syntax '#%kernel))
|
||||||
|
(#%provide begin-encourage-inline)
|
||||||
|
|
||||||
|
;; Attach a property to encourage the bytecode compiler to inline
|
||||||
|
;; functions:
|
||||||
|
(define-syntaxes (begin-encourage-inline)
|
||||||
|
(lambda (stx)
|
||||||
|
(let-values ([(l) (syntax->list stx)])
|
||||||
|
(if l
|
||||||
|
(datum->syntax
|
||||||
|
stx
|
||||||
|
(cons
|
||||||
|
(quote-syntax begin)
|
||||||
|
(map
|
||||||
|
(lambda (form)
|
||||||
|
(syntax-property form
|
||||||
|
'compiler-hint:cross-module-inline
|
||||||
|
#t))
|
||||||
|
(cdr l)))
|
||||||
|
stx
|
||||||
|
stx)
|
||||||
|
(raise-syntax-error #f "bad syntax" stx))))))
|
|
@ -5,7 +5,7 @@
|
||||||
(module map '#%kernel
|
(module map '#%kernel
|
||||||
(#%require '#%utils ; built into mzscheme
|
(#%require '#%utils ; built into mzscheme
|
||||||
"small-scheme.rkt" "define.rkt"
|
"small-scheme.rkt" "define.rkt"
|
||||||
(for-syntax '#%kernel))
|
"../performance-hint.rkt")
|
||||||
|
|
||||||
(#%provide (rename map2 map)
|
(#%provide (rename map2 map)
|
||||||
(rename for-each2 for-each)
|
(rename for-each2 for-each)
|
||||||
|
@ -14,17 +14,8 @@
|
||||||
|
|
||||||
;; -------------------------------------------------------------------------
|
;; -------------------------------------------------------------------------
|
||||||
|
|
||||||
;; Attach a property to encourage the bytecode compiler to inline
|
(begin-encourage-inline
|
||||||
;; `map', etc.:
|
|
||||||
(define-syntax hint-inline
|
|
||||||
(lambda (stx)
|
|
||||||
(syntax-property (cadr (syntax->list stx))
|
|
||||||
'compiler-hint:cross-module-inline
|
|
||||||
#t)))
|
|
||||||
|
|
||||||
;; -------------------------------------------------------------------------
|
|
||||||
|
|
||||||
(hint-inline
|
|
||||||
(define map2
|
(define map2
|
||||||
(let ([map
|
(let ([map
|
||||||
(case-lambda
|
(case-lambda
|
||||||
|
@ -50,9 +41,8 @@
|
||||||
(loop (cdr l1) (cdr l2)))]))
|
(loop (cdr l1) (cdr l2)))]))
|
||||||
(map f l1 l2))]
|
(map f l1 l2))]
|
||||||
[(f . args) (apply map f args)])])
|
[(f . args) (apply map f args)])])
|
||||||
map)))
|
map))
|
||||||
|
|
||||||
(hint-inline
|
|
||||||
(define for-each2
|
(define for-each2
|
||||||
(let ([for-each
|
(let ([for-each
|
||||||
(case-lambda
|
(case-lambda
|
||||||
|
@ -78,9 +68,8 @@
|
||||||
(loop (cdr l1) (cdr l2)))]))
|
(loop (cdr l1) (cdr l2)))]))
|
||||||
(for-each f l1 l2))]
|
(for-each f l1 l2))]
|
||||||
[(f . args) (apply for-each f args)])])
|
[(f . args) (apply for-each f args)])])
|
||||||
for-each)))
|
for-each))
|
||||||
|
|
||||||
(hint-inline
|
|
||||||
(define andmap2
|
(define andmap2
|
||||||
(let ([andmap
|
(let ([andmap
|
||||||
(case-lambda
|
(case-lambda
|
||||||
|
@ -110,9 +99,8 @@
|
||||||
(loop (cdr l1) (cdr l2)))])))
|
(loop (cdr l1) (cdr l2)))])))
|
||||||
(andmap f l1 l2))]
|
(andmap f l1 l2))]
|
||||||
[(f . args) (apply andmap f args)])])
|
[(f . args) (apply andmap f args)])])
|
||||||
andmap)))
|
andmap))
|
||||||
|
|
||||||
(hint-inline
|
|
||||||
(define ormap2
|
(define ormap2
|
||||||
(let ([ormap
|
(let ([ormap
|
||||||
(case-lambda
|
(case-lambda
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#lang scribble/doc
|
#lang scribble/doc
|
||||||
@(require scribble/manual "guide-utils.rkt"
|
@(require scribble/manual "guide-utils.rkt"
|
||||||
(for-label racket/flonum racket/unsafe/ops))
|
(for-label racket/flonum
|
||||||
|
racket/unsafe/ops
|
||||||
|
racket/performance-hint))
|
||||||
|
|
||||||
@title[#:tag "performance"]{Performance}
|
@title[#:tag "performance"]{Performance}
|
||||||
|
|
||||||
|
@ -169,10 +171,8 @@ itself calls functions other than simple primitive operations. When a
|
||||||
module is compiled, some functions defined at the module level are
|
module is compiled, some functions defined at the module level are
|
||||||
determined to be candidates for inlining into other modules; normally,
|
determined to be candidates for inlining into other modules; normally,
|
||||||
only trivial functions are considered candidates for cross-module
|
only trivial functions are considered candidates for cross-module
|
||||||
inlining, but a programmer can attach a
|
inlining, but a programmer can wrap a function definition with
|
||||||
@indexed-racket['compiler-hint:cross-module-inline] @tech[#:doc '(lib
|
@racket[begin-encourage-inline] to encourage inlining
|
||||||
"scribblings/reference/reference.scrbl")]{syntax property} (with a
|
|
||||||
true value) to a function's definition form to encourage inlining
|
|
||||||
of the function.
|
of the function.
|
||||||
|
|
||||||
Primitive operations like @racket[pair?], @racket[car], and
|
Primitive operations like @racket[pair?], @racket[car], and
|
||||||
|
|
|
@ -10,7 +10,8 @@
|
||||||
racket/provide
|
racket/provide
|
||||||
racket/package
|
racket/package
|
||||||
racket/splicing
|
racket/splicing
|
||||||
racket/runtime-path))
|
racket/runtime-path
|
||||||
|
racket/performance-hint))
|
||||||
|
|
||||||
@(define require-eval (make-base-eval))
|
@(define require-eval (make-base-eval))
|
||||||
@(define syntax-eval
|
@(define syntax-eval
|
||||||
|
@ -2084,9 +2085,9 @@ z
|
||||||
If a @racket[define-values] form for a function definition in a module
|
If a @racket[define-values] form for a function definition in a module
|
||||||
body has a @indexed-racket['compiler-hint:cross-module-inline]
|
body has a @indexed-racket['compiler-hint:cross-module-inline]
|
||||||
@tech{syntax property} with a true value, then the Racket treats the
|
@tech{syntax property} with a true value, then the Racket treats the
|
||||||
property as a performance hint. See
|
property as a performance hint. See
|
||||||
@guidesecref["func-call-performance"] in @|Guide| for more
|
@guidesecref["func-call-performance"] in @|Guide| for more
|
||||||
information.}
|
information, and see also @racket[begin-encourage-inline].}
|
||||||
|
|
||||||
|
|
||||||
@defform*[[(define-syntax id expr)
|
@defform*[[(define-syntax id expr)
|
||||||
|
@ -2591,3 +2592,14 @@ syntactic forms or languages that supply a more limited kind of
|
||||||
|
|
||||||
@close-eval[require-eval]
|
@close-eval[require-eval]
|
||||||
@close-eval[meta-in-eval]
|
@close-eval[meta-in-eval]
|
||||||
|
|
||||||
|
@;------------------------------------------------------------------------
|
||||||
|
@section[#:tag "performance-hint"]{Performance Hints: @racket[begin-encourage-inline]}
|
||||||
|
|
||||||
|
@note-lib-only[racket/performance-hint]
|
||||||
|
|
||||||
|
@defform[(begin-encourage-inline form ...)]{
|
||||||
|
|
||||||
|
Attaches a @racket['compiler-hint:cross-module-inline]
|
||||||
|
@tech{syntax property} to each @racket[form], which is useful when a
|
||||||
|
@racket[form] is a function definition. See @racket[define-values].}
|
||||||
|
|
|
@ -1382,16 +1382,16 @@
|
||||||
(null? 10)))
|
(null? 10)))
|
||||||
|
|
||||||
(module check-inline-request racket/base
|
(module check-inline-request racket/base
|
||||||
|
(require racket/performance-hint)
|
||||||
(provide loop)
|
(provide loop)
|
||||||
(define loop
|
(begin-encourage-inline
|
||||||
(begin
|
(define loop
|
||||||
'compiler-hint:cross-module-inline
|
;; large enough that the compiler wouldn't infer inlining:
|
||||||
;; large enough that the compiler wouldn't infer inlining:
|
(lambda (f n)
|
||||||
(lambda (f n)
|
(let loop ([i n])
|
||||||
(let loop ([i n])
|
(if (zero? i)
|
||||||
(if (zero? i)
|
10
|
||||||
10
|
(cons (f i) (loop (sub1 n)))))))))
|
||||||
(cons (f i) (loop (sub1 n)))))))))
|
|
||||||
|
|
||||||
(test-comp `(module m racket/base
|
(test-comp `(module m racket/base
|
||||||
(require 'check-inline-request)
|
(require 'check-inline-request)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user