Subject: [clisp-list] Please try out FFI speed improvement

From: "Hoehle, Joerg-Cyril" <[email-masked]>
Date: Wed Mar 26 06:37:15 2003

Hi FFI users,

Aurelio Bignoli wrote:
>ad-hoc C function:
>   Real time: 0.181583 sec.
>with-c-var/cast:
>   Real time: 1.494392 sec.
Ouch! 10 times slower...
>with-foreign-object/%cast
>   Real time: 0.638666 sec.
WITH-FOREIGN-OBJECT still embeds a superfluous call to PARSE-C-TYPE.

Could you please try out the following:
;; An initial attempt at better run-time behaviour: there is often
;; no need to reparse for every function call.
;; Even better would even be compile-time inlining of parse-c-type result,
;; when applicable (only combinations of uint, char, c-array etc., no c-struct nor def-c-type)
(define-compiler-macro ffi::parse-c-type (typespec &optional name &whole form)
  (if (and (null name)
           (consp typespec)
           (eq 'QUOTE (car typespec)))
      `(LOAD-TIME-VALUE (FFI::PARSE-C-TYPE ',(cadr typespec)))
      form))

I expect this code to work under all (if not 98%) current uses of the CLISP FFI. Depending on LOAD-TIME-VALUE means that in theory, problems could occur with things not yet defined at the time a file is loaded (e.g. late definitions etc.).

However, I believe there's very little use of this opportunity in actual code, since the FFI has been underspecified in this area anyway: When should a foreign type definition be available? Compile-time? X-time?

So far, foreign1.lisp has (carelessly?) enforced a restrictive use on DEF-CALL-OUT etc. forms: the foreign types where (superfluously?) checked by the compiler, for the single benefit of knowing the argument count of a foreign function. This is not necessary (but nobody complained).

Therefore, load-time-value should work well with (load&)compile-time known types.

In a VM machine like CLISP, unlike native-code generation, there's little value in having C types known at compile-time. That's why I had no problem having WITH-FOREIGN-OBJECT and WITH-C-VAR evaluate the type, whereas e.g. CMUCL's WITH-ALIEN does not:

#+clisp (with-foreign-object (x (compute-foreign-type)) body)
#+clisp (with-foreign-object (x '(c-array uint8 32)) body)
#+cmu   (with-alien          (x (array c-call:uint8 32)) body)
Note the missing 'quote for CMUCL.

Note that you'll need clisp>2.28, because of a bug-fix to compiler-macrolet which I reporetd a few month ago.

Regards,
	Jorg Hohle.

---

From: Aurelio Bignoli <[email-masked]>
Date: Thu Mar 27 14:32:15 2003

> Could you please try out the following:

with-c-var/cast

   Real time: 1.273894 sec. (it was 1.494392)
   Run time: 1.09 sec. (it was 1.17)
   Space: 3440000 Bytes
   GC: 4, GC time: 0.54 sec.

   Real time: 0.521461 sec. (it was 0.638666)
   Run time: 0.44 sec. (it was 0.54)
   Space: 1520000 Bytes
   GC: 2, GC time: 0.27 sec.

 > I expect this code to work under all (if not 98%) current uses of
 > the CLISP FFI. Depending on LOAD-TIME-VALUE means that in theory,
 > problems could occur with things not yet defined at the time a file
 > is loaded (e.g. late definitions etc.).

my FFI code for Berkeley DB works fine with this new definition.