Hi,
I have recently switched to using the cffi+lotsastuff version and I find it very slow for certain applications. The reason for this is that PARSE-TYPE is called from FOREIGN-TYPE-SIZE, and PARSE-TYPE is very expensive. It would be relatively easy to cache the type parsing results in a hash table, but before moving forward in that direction, I'd like to know what your opinions on this is.
Thanks, Hans
On Fri, May 30, 2008 at 3:21 PM, Hans Hübner hans@huebner.org wrote:
I have recently switched to using the cffi+lotsastuff version and I find it very slow for certain applications. The reason for this is that PARSE-TYPE is called from FOREIGN-TYPE-SIZE, and PARSE-TYPE is very expensive. It would be relatively easy to cache the type parsing results in a hash table, but before moving forward in that direction, I'd like to know what your opinions on this is.
PARSE-TYPE has been slow ever since it started to check for cycles. This change is not specific to the cffi+lotsastuff branch:
A few weeks ago, some optimizations to PARSE-TYPE and FOREIGN-ALLOC (which was calling PARSE-TYPE more often than necessary). What's your use case?
On Fri, May 30, 2008 at 5:49 PM, Luís Oliveira luismbo@gmail.com wrote:
PARSE-TYPE has been slow ever since it started to check for cycles. This change is not specific to the cffi+lotsastuff branch:
We are using the latest release version of CFFI internally, and I have tried out the cffi+lotsastuff branch as we are interested in the integration of Babel. When I switched to the branch, I saw the performance of our application drop dramatically, and the profiler showed that run time is dominated by calls to PARSE-TYPE. I have implemented a caching mechanism as a cure, but as that is not thread safe, it is not a general solution.
A few weeks ago, some optimizations to PARSE-TYPE and FOREIGN-ALLOC (which was calling PARSE-TYPE more often than necessary). What's your use case?
Every invocation of FOREIGN-STRING-ALLOC eventually invokes PARSE-TYPE, and we use it a lot.
-Hans
On Fri, May 30, 2008 at 5:13 PM, Hans Hübner hans@huebner.org wrote:
A few weeks ago, some optimizations to PARSE-TYPE and FOREIGN-ALLOC (which was calling PARSE-TYPE more often than necessary). What's your use case?
Ugh. That should read "some optimizations ... were made".
Every invocation of FOREIGN-STRING-ALLOC eventually invokes PARSE-TYPE, and we use it a lot.
Thanks to the optimization mentioned above (a compiler macro for foreign-alloc), foreign-string-alloc calls PARSE-TYPE only at compile-time.
My guess is that the PARSE-TYPE calls you're seeing are coming from FOREIGN-ENUM-{VALUE,KEYWORD}, which is one of the few places where calls to PARSE-TYPE at runtime haven't been optimized away into compile-time, yet. Can you confirm this?
On Fri, May 30, 2008 at 7:27 PM, Luís Oliveira luismbo@gmail.com wrote:
On Fri, May 30, 2008 at 5:13 PM, Hans Hübner hans@huebner.org wrote:
Every invocation of FOREIGN-STRING-ALLOC eventually invokes PARSE-TYPE, and we use it a lot.
Thanks to the optimization mentioned above (a compiler macro for foreign-alloc), foreign-string-alloc calls PARSE-TYPE only at compile-time.
This seems not to work on Clozure CL the way that it is expected. I see a call to PARSE-TYPE for every invocation of FOREIGN-STRING-ALLOC. I will try to understand how the compiler macro is supposed to work in order to find out if what I see is a CCL bug and can be fixed by Clozure. Any pointers helping with that would be appreciated.
Thank you for the clarification so far, Hans
On Fri, May 30, 2008 at 8:08 PM, Hans Hübner hans@huebner.org wrote:
On Fri, May 30, 2008 at 7:27 PM, Luís Oliveira luismbo@gmail.com wrote:
Thanks to the optimization mentioned above (a compiler macro for foreign-alloc), foreign-string-alloc calls PARSE-TYPE only at compile-time.
Actually, PARSE-TYPE is only called when FOREIGN-STRING-ALLOC itself is compiled. No type parsing occurs when FOREIGN-STRING-ALLOC is called, either at compile-time or runtime. Assuming the FOREIGN-ALLOC compiler macro kicks in, of course.
This seems not to work on Clozure CL the way that it is expected. I see a call to PARSE-TYPE for every invocation of FOREIGN-STRING-ALLOC. I will try to understand how the compiler macro is supposed to work in order to find out if what I see is a CCL bug and can be fixed by Clozure. Any pointers helping with that would be appreciated.
CFFI> (trace parse-type) NIL CFFI> (ccl:compiler-macroexpand-1 '(foreign-alloc :char :count length)) 0> Calling (PARSE-TYPE :CHAR) <0 PARSE-TYPE returned #<FOREIGN-BUILT-IN-TYPE :CHAR> (%FOREIGN-ALLOC (* LENGTH 1)) T
That is how the FOREIGN-ALLOC compiler macro gets rid of the PARSE-TYPE call in FOREIGN-STRING-ALLOC. And it seems to work here.
CFFI> (foreign-string-alloc "foo") #<A Foreign Pointer #x65BE80> 4 ;; no call to PARSE-TYPE there
FWIW, I'm using "Version 1.2-r9017-trunk (LinuxX8664)".
On Fri, May 30, 2008 at 10:55 PM, Luís Oliveira luismbo@gmail.com wrote:
On Fri, May 30, 2008 at 8:08 PM, Hans Hübner hans@huebner.org wrote:
On Fri, May 30, 2008 at 7:27 PM, Luís Oliveira luismbo@gmail.com wrote:
Thanks to the optimization mentioned above (a compiler macro for foreign-alloc), foreign-string-alloc calls PARSE-TYPE only at compile-time.
Actually, PARSE-TYPE is only called when FOREIGN-STRING-ALLOC itself is compiled. No type parsing occurs when FOREIGN-STRING-ALLOC is called, either at compile-time or runtime. Assuming the FOREIGN-ALLOC compiler macro kicks in, of course.
It seemingly does not:
CFFI> (trace parse-type) NIL CFFI> (foreign-string-alloc "foo") 0> Calling (PARSE-TYPE :CHAR) <0 PARSE-TYPE returned #<FOREIGN-BUILT-IN-TYPE :CHAR> 0> Calling (PARSE-TYPE :UINT8) <0 PARSE-TYPE returned #<FOREIGN-TYPEDEF :UINT8> 0> Calling (PARSE-TYPE :UINT8) <0 PARSE-TYPE returned #<FOREIGN-TYPEDEF :UINT8> 0> Calling (PARSE-TYPE :UINT8) <0 PARSE-TYPE returned #<FOREIGN-TYPEDEF :UINT8> 0> Calling (PARSE-TYPE :CHAR) <0 PARSE-TYPE returned #<FOREIGN-BUILT-IN-TYPE :CHAR> #<A Foreign Pointer #x2AAAB963F6D0> 4 CFFI> (lisp-implementation-version) "Version 1.2-r9471M (LinuxX8664)"
So, if I understand what you write, this basically means that the FOREIGN-ALLOC compiler macro does not work. I will try to isolate this and ask the Clozure folks for help.
Thanks! Hans
On Fri, May 30, 2008 at 5:13 PM, Hans Hübner hans@huebner.org wrote:
On Fri, May 30, 2008 at 7:27 PM, Luís Oliveira luismbo@gmail.com wrote:
Thanks to the optimization mentioned above (a compiler macro for foreign-alloc), foreign-string-alloc calls PARSE-TYPE only at compile-time.
It seemingly does not:
CFFI> (trace parse-type) NIL CFFI> (foreign-string-alloc "foo") 0> Calling (PARSE-TYPE :CHAR) <0 PARSE-TYPE returned #<FOREIGN-BUILT-IN-TYPE :CHAR> 0> Calling (PARSE-TYPE :UINT8) <0 PARSE-TYPE returned #<FOREIGN-TYPEDEF :UINT8> 0> Calling (PARSE-TYPE :UINT8) <0 PARSE-TYPE returned #<FOREIGN-TYPEDEF :UINT8> 0> Calling (PARSE-TYPE :UINT8) <0 PARSE-TYPE returned #<FOREIGN-TYPEDEF :UINT8> 0> Calling (PARSE-TYPE :CHAR) <0 PARSE-TYPE returned #<FOREIGN-BUILT-IN-TYPE :CHAR> #<A Foreign Pointer #x2AAAB963F6D0> 4 CFFI> (lisp-implementation-version) "Version 1.2-r9471M (LinuxX8664)"
So, if I understand what you write, this basically means that the FOREIGN-ALLOC compiler macro does not work. I will try to isolate this and ask the Clozure folks for help.
The reason for this was the very high debug and safety optimization settings (safety 3 debug 3) that have been in use when compiling the application. When compiling with (debug 1 safety 2), the compiler macro is used as expected.
Thanks! Hans