[Top][All Lists]
[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)))
- [Chicken-users] Returning a void * by reference,
Zbigniew <=