I eventually implemented this outside bigloo by creating type specific versions of functions. Now my problem is that previously I could define-generic in module A, and then call a typed version of that in module B from module C, if C imported A but not B. Direct function calls must be made to modules directly imported though and I don't want to change my dependency graph, so I'm just going to emit a warning and call the generic function in that case. I'm hoping Sven's scmc tool might help get around this.
 
-----------
 
Thanks very much, I haven't been using the -ast flag.
I'm generating Bigloo code so can implement this at that stage, but adding it to Bigloo itself might be useful as well - I'll have a look.
 
Sent: Thursday, August 11, 2016 at 3:31 PM
From: [email protected]
To: "bob eob" <[email protected]>
Cc: [email protected]
Subject: Re: [bigloo] types and generic function performance
Hi Bob,

> Hello and thanks for writing Bigloo!
>
> I have a question about performance ... I wrote this program:
>
> ;------------------------
> (module test
> (main scm-main)
> (export
> (class TestClass)
> ))
>
> (define-generic (test-func obj) (print "GENERIC METHOD"))
> (define-method (test-func obj::TestClass) (print "TEST METHOD"))
>
> (define (scm-main argv)
> (let ((tc::TestClass (instantiate::TestClass)))
> (test-func tc)))
>
> ;------------------------
>
> Which works as expected, producing the output "TEST METHOD", but if I look at the generated C code it looks like it is calling test-func dynamically even though I have specified the class type with tc::TestClass.
>
>
>
> Is there some way to make such generic functions faster by calling the correct define-method function directly if the type is known?
>
> Thanks,
You are correct in your observation. The compiler does not implement
this optimization. I have never conducted any experiment to check if
it would frequently apply in practice.

As it is, the calling a method instead of a regular function incurs a
couple of memory read + a indirect call. Your function TEST-FUNC is compiled
as follows:

(define-generic (test-func obj)
(let ((test1086 (object? obj)))
(if test1086
(let ((method1053
(unsafe (find-method obj (closure test-func)))))
(funcall method1053 method1053 obj))
(let ((fun1087 (generic-default (closure test-func))))
(funcall fun1087 fun1087 obj)))))

and FIND-METHOD is defined by:

(define-inline (find-method obj generic)
(let ((obj-class-num (object-class-num obj)))
(method-array-ref generic (generic-method-array generic) obj-class-num)))


You can check this with bigloo -unsafe -O2 -fno-user-inlining -ast

Cheers,

--
Manuel

Reply via email to