Image using high CPU in WeakIdentityKeyDictionary>>scanFor:

Daniel Vainsencher daniel.vainsencher at gmail.com
Tue Sep 20 04:47:43 UTC 2005


Actually the scanfor of weakIDDicts in 3.9a is reasonable looking (as 
opposed, for example to weakset, weakkeydict, Dictionary, Set and so 
forth, which are quite terrible above ~3000 entries. I'm talking 
specifically about the calculation of "start", which really determines 
how well the hash values will be spread out.

Ross, can you post WeakIDDict>>scanFor: as implemented in your image? 
just to make sure.

Ross, my advice is:
1. I notice your time in this dictionary stems from dependent 
notification. Consider a switch to the local implementation of 
dependencies. A little more detail:
Object implements all dependents using one global dictionary, that 
therefore might get large. Other classes have local storage for those 
(see implementors of actionMap). This might not help if you have one 
object with thousands of dependents, but might solve the problem 
outright otherwise.
2. Try to make a simple TestCase that exhibits the same performance 
issues at the same scales, that other people can load and look at.
3. As Dave said, look at the instances in your image. How many such 
dictionaries do you have? how big are they? what percentages of the 
associations in them have nil keys (careful about the code you use - 
associationsDo: ignores nil keys in some versions).

Daniel

David T. Lewis wrote:
> On Mon, Sep 19, 2005 at 01:26:46PM -0700, Ross Boylan wrote:
> 
>>I continue to have major problems with squeak taking up all the CPU
>>and becoming extraordinarily sluggish (e.g., 15 seconds to respond to
>>click, minutes to complete some operations).
>>
>>A TimeProfile while the system was doing nothing showed virtually all
>>(99.4%) the time going to WeakIdentityDictionary>>scanFor:.  This time
>>is roughly evenly split between primitives and
>>WeakKeyAssociation>>key.
> 
> 
> This sounds rather familiar all of the sudden. I think that I have
> seen similar behavior associated with the WeakRegistry in class
> StandardFileStream (and Socket, although in my case StandardFileStream
> was the issue).
> 
> The problem I saw was that #scanFor: degraded horribly when there
> were a lot of entries in the WeakRegistry. In normal Squeak usage,
> this did not happen, but in my case I was accidentally accumulating
> a lot of entries in the registry (*).
> 
> Take a look a the WeakIdentityDictionaries in your application. I'll
> bet you have one or two of them with a large number of entries, and
> your "CPU problem" may be happening when one of those critters gets
> too big and you need to insert more elements into it.
> 
> I don't recall the details, but I do remember that #scanfor: was the
> issue. If this turns out be be the problem you are seeing, perhaps
> someone with a knack for algorithms could take a look at it and
> propose a #scanfor: that degrades more gracefully with size.
> 
> Dave
> 
> (*) Specifically, I was using a subclass of StandardFileStream to
> represent the end points of an operating system pipe; then I made
> and destroyed large numbers of these in the course of making command
> pipelines (see CommandShell on SqueakMap). After running a large
> number of SUnit tests, these things would accumulate in the registry
> to the point where performance degraded horribly. Once I found the
> culprit, I just quit registering the pipe endpoints (which of course
> are transient things that don't need to be registered), and my
> "CPU problem" went away.
> 
> 



More information about the Squeak-dev mailing list