Here in Racket v8.10 CS I have implemented unsafe-set-car!
in a way that is equivalent (I think) to unsafe-set-immutable-car!
which is provided by racket/unsafe/ops
:
#lang racket/base
(module prim racket/base
(require ffi/unsafe/vm)
(provide unsafe-set-car!)
(vm-eval '(define-syntax (unsafe-primitive stx)
(syntax-case stx ()
[(_ id)
#'($primitive 3 id)])))
(define unsafe-set-car!
(vm-eval '(parameterize ([optimize-level 3])
(lambda (p a) ((unsafe-primitive set-car!) p a))))))
(require racket/unsafe/ops
'prim)
(let ([p (cons 1 2)])
(time
(for ([i (in-range 100000000)])
(unsafe-set-car! p i)
;;(unsafe-set-immutable-car! p i)
)))
I assumed that unsafe-set-car!
and unsafe-set-immutable-car!
would be of almost equal speed in that loop, but they weren't.
That method of using virtual machine primitives is the most performant that I know of. Am I missing something in it?
I'm more interested in procedures based on the hashtable
primitives but there are no corresponding Racket-level unsafe versions to compare them to, so I used the set-car!
primitive as an example instead. The slowness occurs with other primitives too.