Bug 127996 - Performance: long time spent in State.write(..) looping over ArrayList<char[][]>
Summary: Performance: long time spent in State.write(..) looping over ArrayList<char[][]>
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.2   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.2 M6   Edit
Assignee: Kent Johnson CLA
QA Contact:
URL:
Whiteboard:
Keywords: performance
Depends on:
Blocks:
 
Reported: 2006-02-15 05:32 EST by Markus Keller CLA
Modified: 2006-03-27 12:55 EST (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Markus Keller CLA 2006-02-15 05:32:09 EST
I20060215-0010

The shutdown of my runtime workbench took a long time with no progress (message "Saving Workspace"), so I suspended all threads and checked what was going on. I found that all the time was spent in org.eclipse.jdt.internal.core.builder.State.write(..) in the last big loop.

Some numbers:
references.elementSize= 1864
keyTable.length= 3453
internedQualifiedNames.size= 12831
internedSimpleNames.size= 12097

For every element in the keyTable, there are two loops like this:
	for (int j = 0; j < qLength; j++)
		out.writeInt(internedQualifiedNames.indexOf(qNames[j]));

Unless I miss something fundamental here, I think it is very inefficient to loop over these big ArrayLists again and again comparing all the char[][] and char[][][] just to find a matching element. I guess a hash table would be appropriate to speed this up.

I disabled autobuild and killed the build job shortly before - don't know if that has an influence here.
Comment 1 Kent Johnson CLA 2006-02-15 11:33:05 EST
indexof is using == to do the comparison so unless the interned arrays are 100,000 elements then I doubt this the reason it was slow to save your workspace.
Comment 2 Markus Keller CLA 2006-02-15 14:00:49 EST
java.util.ArrayList#indexOf(..) uses Object#equals(..) to find elements.

I've set a breakpoint after the loop and that breakpoint was not hit for a long time, so I'm pretty sure the time was burned in this loop. I also suspended the vm manually, and it was inside indexOf(..) most of the time.

I don't know how big qNames and sNames grow, but if I assume they contain just 1 element, then the number of calls to char[]#equals(..) is in average:

    references.elementSize * 2 *
            (internedQualifiedNames.size + internedSimpleNames.size) / 2

    = 46'465'792 calls
Comment 3 Kent Johnson CLA 2006-02-15 14:57:34 EST
What does equals do for a char[] -> == 

I have no idea what you think that expression meant.
Comment 4 Markus Keller CLA 2006-02-16 05:03:32 EST
> What does equals do for a char[] -> == 

Of course, but there are still (rough guess) more than 46 Million calls to an equals method. And that is a lot, even if they were plain == operations.
Comment 5 Kent Johnson CLA 2006-02-17 13:06:40 EST
Fixed.

Will have a big impact on very large projects.
Comment 6 Frederic Fusier CLA 2006-03-27 12:55:28 EST
Verified for 3.2 M6 using warm-up build I20060327-0010.
Unfortunately, close workspace operation does not long enough on our full source workspace to add a specific performance test case...