Protocol call-site caching for explicitly typed members

344 views
Skip to first unread message

Zach Tellman

unread,
May 18, 2013, 12:34:37 AM5/18/13
to cloju...@googlegroups.com
I came across this a while back, and have been meaning to bring this up here.  In short, members which are explicitly typed incur the same protocol call-site caching overhead as members which are untyped.  This is shown in more detail at https://gist.github.com/ztellman/5603216.

This was discovered in the course of investigating memory usage of an object which had a small number of fields, but a lot of code.  Since the protocols were for internal usage I switched to interfaces instead, and the memory usage of this object was reduced twenty-fold.  Even though I understood the basics of call-site caching, this surprised me quite a bit, and I'm sure there are a number of other people who are affected by this.

I don't have a deep understanding of the compiler, but it seems like if we know the type of an object, the protocol dispatch can and should be sidestepped entirely.  Is there a reason this isn't possible?  If not, is it an easy fix?

Zach

Kevin Downey

unread,
May 18, 2013, 3:19:46 AM5/18/13
to Clojure Dev
I think the "fix" here would be to some kind of invokedynamic callsite (maybe a switchpoint).

Linking the implementation directly may work ok for types that directly implement protocols, because the implementation for that type is (at least as things currently stand) fixed at compile time and not changeable via extend-protocol.

For types that have had protocols extended to them after the fact (with extend-protocol) you can come a long and re-extend the protocol with a different implementation, so no direct linking there.

And even for the first case direct linking will cause trouble when types are redefined, and there are already plenty of pain points around that.



Zach

--
You received this message because you are subscribed to the Google Groups "Clojure Dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure-dev...@googlegroups.com.
To post to this group, send email to cloju...@googlegroups.com.
Visit this group at http://groups.google.com/group/clojure-dev?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.
 
 



--
And what is good, Phaedrus,
And what is not good—
Need we ask anyone to tell us these things?

Zach Tellman

unread,
May 18, 2013, 1:31:05 PM5/18/13
to cloju...@googlegroups.com
Yeah, I was only referring to direct protocol implementation, but as you point out that that's already fraught with situations where interfaces are inconsistently shadowed by other interfaces with the same name.

Maybe an easier short-term fix is to just reuse call-site caching for the same members.  I think that would place enough of an upper-bound on memory usage that I wouldn't have even noticed it in the first place.

Zach Tellman

unread,
May 28, 2013, 5:32:57 PM5/28/13
to cloju...@googlegroups.com
A consequence of this that I hadn't realized before is that any use of clojure.tools.logging adds memory overhead to the object, since it uses protocols.

There hasn't been a lot of conversation on this thread, even though it strikes me as something that's a pretty big issue for some real-world use cases.  Am I wrong in this?  Has this been the expected behavior for everyone else?

Mikera

unread,
May 28, 2013, 8:41:30 PM5/28/13
to cloju...@googlegroups.com
On Wednesday, 29 May 2013 05:32:57 UTC+8, Zach Tellman wrote:
A consequence of this that I hadn't realized before is that any use of clojure.tools.logging adds memory overhead to the object, since it uses protocols.

There hasn't been a lot of conversation on this thread, even though it strikes me as something that's a pretty big issue for some real-world use cases.  Am I wrong in this?  Has this been the expected behavior for everyone else?


I'm not knowledgeable enough on the protocol implementation to comment on how it is implemented, but it looks like the consequences could be pretty nasty for some plausible core.matrix use cases. Things like complex number implementations, for example, could have a *lot* of callsites. I definitely think we should try and fix it.

Do we really want/need callsite caching on a per-instance basis? This seems like a lot of overhead, especially for deftype which is supposed to produce lightweight objects....

Ghadi Shayban

unread,
May 29, 2013, 12:36:48 AM5/29/13
to cloju...@googlegroups.com
I'm working on a better rationale for this (and that's why I closed it), but try out the patch on CLJ-1211
I'm curious to see if it helps or hurts your real-world use cases.

Zach Tellman

unread,
May 30, 2013, 5:02:57 PM5/30/13
to cloju...@googlegroups.com
Am I reading correctly that these fields are vestigial?  If so, why do we need a better rationale to get rid of them?


--

Alan Malloy

unread,
May 31, 2013, 12:45:40 AM5/31/13
to cloju...@googlegroups.com
Judging by the patch, they are clearly not vestigial: the compiler generates fields for the object, and reads and writes them in order to cache protocol dispatches. His patch removes the caching, so that it still "works" but without the optimization.

Alan Malloy

unread,
May 31, 2013, 1:25:45 PM5/31/13
to cloju...@googlegroups.com
Ghadi straightened me out via IRC. The compiler generates code that looks an awful lot like it's doing inline caching, but in fact it is just wasting space (and a little time).

Rich Hickey

unread,
May 31, 2013, 3:24:07 PM5/31/13
to cloju...@googlegroups.com

On May 28, 2013, at 5:32 PM, Zach Tellman <ztel...@gmail.com> wrote:

> A consequence of this that I hadn't realized before is that any use of clojure.tools.logging adds memory overhead to the object, since it uses protocols.
>
> There hasn't been a lot of conversation on this thread, even though it strikes me as something that's a pretty big issue for some real-world use cases. Am I wrong in this? Has this been the expected behavior for everyone else?
>

I'm sorry I haven't had time yet to chime in on this. I appreciate your concern and will look into it. Any issues will be rectified in 1.6.

Thanks,

Rich
Reply all
Reply to author
Forward
0 new messages