chicken-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Chicken-users] Returning a void * by reference


From: Zbigniew
Subject: [Chicken-users] Returning a void * by reference
Date: Wed, 23 Nov 2005 21:12:00 -0600

Here's another interesting performance note, and I assure you
everything is compiled this time.

I have a C function which returns a void * by reference (i.e. it takes
a void ** as argument).  I was using let-location, but I found that if
you pass a #<pointer> object as a scheme-pointer, it works just as
well and is about twice as fast.

Okay, now the interesting part.  In numerous places, such as tcp.scm,
a string object is allocated and passed as a scheme-pointer so it can
be filled.  This is the same as taking my #<pointer> example above and
changing it to (make-string 4), assuming 32 bit pointers.

What I found is that replacing (##sys#make-pointer) with (make-string
4) incurs a huge number of garbage collections and is slow.  What's
more, using (make-byte-vector 4) does NOT have this problem!  I have
no idea why, as the implementation looks nearly identical to me
(basically, ##sys#allocate-vector).  These results are repeatable for
me.

I can rewrite any occurrences of make-string to make-byte-vector, but
I am curious if anyone has an explanation.

#;4> ,t (e1-spp 1000000)              ;; Passing a #<pointer>.
   0.708 seconds elapsed
       0 seconds in (major) GC
       3 mutations
    5309 minor GCs
       0 major GCs
done

#;3> ,t (e1-spbv 1000000)             ;; Passing a (make-byte-vector 4).
   0.957 seconds elapsed
  2.e-03 seconds in (major) GC
       2 mutations
     126 minor GCs
       2 major GCs
done

#;5> ,t (e1-sp 1000000)                 ;; Passing a (make-string 4).
   2.683 seconds elapsed
   1.564 seconds in (major) GC
       3 mutations
       3 minor GCs
    1202 major GCs                         ;; <----- eh?
done


Here's the relevant code.

(use lolevel)

(define callback1-scheme-pointer
  (foreign-lambda* int ((scheme-pointer buffer)) #<<EOF
    static char a[] = "hello";
    void **b = (void **)buffer;
    *b = a;
    return(1);
EOF
))

;; Make a 4-byte string instead of using a let-location.
;; callback1-scheme-pointer expects a scheme-pointer this time.
(define (execute1-scheme-pointer)
  (let ((p (make-string 4)))     ;; equal results from ##sys#make-string
    (let ((result (callback1-scheme-pointer p)))
      p)))

;; same as execute1-scheme-pointer but dumping directly into
;; a #<pointer> rather than a string
(define (execute1-scheme-pointer-ptr)
  (let ((p (##sys#make-pointer)))
    (let ((result (callback1-scheme-pointer p)))
      p)))

;; same, dumping into 4-byte byte-vector
(define (execute1-scheme-pointer-bv)
  (let ((p (make-byte-vector 4)))
    (let ((result (callback1-scheme-pointer p)))
      p)))




reply via email to

[Prev in Thread] Current Thread [Next in Thread]