Bug 83750 - [perf] Excessive File.isFile calls for clients of JavaModel.getTarget(...)
Summary: [perf] Excessive File.isFile calls for clients of JavaModel.getTarget(...)
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.1   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.1 M7   Edit
Assignee: Frederic Fusier CLA
QA Contact:
URL:
Whiteboard:
Keywords: performance
Depends on:
Blocks: 61944
  Show dependency tree
 
Reported: 2005-01-26 14:01 EST by Dan Kehn CLA
Modified: 2005-05-12 04:27 EDT (History)
5 users (show)

See Also:


Attachments
JavaModel.isFile and getFile convenience methods (12.29 KB, application/octet-stream)
2005-01-26 14:06 EST, Dan Kehn CLA
no flags Details
JavaProject use JavaModel.isFile (search on dbk) (96.20 KB, application/octet-stream)
2005-01-26 14:07 EST, Dan Kehn CLA
no flags Details
PackageFragmentRoot use JavaModel.getFile (search on dbk) (27.51 KB, application/octet-stream)
2005-01-26 14:08 EST, Dan Kehn CLA
no flags Details
JavaCore use JavaModel.getFile (search on dbk) (160.05 KB, application/octet-stream)
2005-01-26 14:09 EST, Dan Kehn CLA
no flags Details
ClasspathEntry use JavaModel.getFile (search on dbk) (48.25 KB, application/octet-stream)
2005-01-26 14:10 EST, Dan Kehn CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Dan Kehn CLA 2005-01-26 14:01:44 EST
Build: I20050126-0800

BACKGROUND:

I am working with the JVE team to improve their editor's performance. One 
significant difference between the Visual Editor open time and the JDT's Java 
editor open time is I/O -- the former often makes 10-20x more I/O events.

PROBLEM:

We're making good progress reducing the Visual Editor's I/O. During my 
investigation, I also found the JDT is contributing to unnecessary I/O events 
(confirmed with FileMon and traced to File.isFile invocations). 

I noted that many callers of the JavaModel.getTarget(...) method, such as 
IJavaProject.getAllPackageFragmentRoots, have subsequent tests of File.isFile
(), which is equivalent in cost to File.exists() that the 
JavaModel.existingExternalFiles cache wishes to avoid. In the scenario I 
measured, added a second cache (existingExternalConfirmedFiles) avoided 78 I/O 
events or almost 30% of all the remaining I/O events for the JVE "open editor" 
testcase. During a launch, this correction also saves more I/O calls, although 
I didn't measure them precisely since that occurs on the JVE's background 
thread.

PROPOSED CORRECTION:

I have attached a version of JavaModel adding two convenience methods: isFile 
and getFile, whose purpose is to cache the previously determined status of the 
given target in the static field existingExternalConfirmedFiles. Also attached 
are several clients of these APIs. I offer them as suggestions, although 
judging from the nested if...else...if...else that generally follows the 
invocation of JavaModel.getTarget, there may be a more elegant way of 
capturing the intent by adding added conditions / flags to this API rather 
than the simplistic performance-oriented approach I've taken.
Comment 1 Dan Kehn CLA 2005-01-26 14:06:13 EST
Created attachment 17479 [details]
JavaModel.isFile and getFile convenience methods
Comment 2 Dan Kehn CLA 2005-01-26 14:07:47 EST
Created attachment 17480 [details]
JavaProject use JavaModel.isFile (search on dbk)
Comment 3 Dan Kehn CLA 2005-01-26 14:08:38 EST
Created attachment 17481 [details]
PackageFragmentRoot use JavaModel.getFile (search on dbk)
Comment 4 Dan Kehn CLA 2005-01-26 14:09:48 EST
Created attachment 17482 [details]
JavaCore use JavaModel.getFile (search on dbk)
Comment 5 Dan Kehn CLA 2005-01-26 14:10:33 EST
Created attachment 17483 [details]
ClasspathEntry use JavaModel.getFile (search on dbk)
Comment 6 Philipe Mulet CLA 2005-01-26 16:58:09 EST
The caching approach is interesting, though a cache need to be updated to be
useful (i.e. if a file becomes unavailable, the cache must not hide this fact).

Jerome - can you please look at it ? Feels like a good perf issue.

Comment 7 Dan Kehn CLA 2005-01-26 17:21:53 EST
Thanks Philippe, all improvements are welcome.  

The issue of keeping the cache in sync already exists for the current 
JavaModel.existingExternalFiles variable. I added clearing the new 
JavaModel.existingExternalConfirmedFiles to the flushExternalFileCache() 
method assuming this would cover it.

FYI: With this and all the other I/O optimizations in place denoted in bug 
61944, the current score for a warm editor open is JDT 164 I/O events versus 
JVE 338. That's probably as good as we can do without prefetching the JVE 
model (similar to your persisted JavaModel cache). Back to CPU usage 
analysis...
Comment 8 Tod Creasey CLA 2005-03-07 11:57:25 EST
Adding my name to the cc list as we are now tracking performance issues more
closely. Please remove the performance keyword if this is not a performance bug.
Comment 9 Dan Kehn CLA 2005-03-07 12:14:13 EST
Thanks Tod, it is and remains a performance issue (small but measurable).
Comment 10 Philipe Mulet CLA 2005-04-06 05:26:51 EDT
Pls investigate if anything realistic can be made.

Re: comment#7.
No the external file cache is not meant to be updated frequently, and hooking
into it will not allow you keep up with normal development. It is only meant to
cache immutable files (binaries).
Comment 11 Mike Wilson CLA 2005-04-25 13:41:33 EDT
How long does it take to open an editor, and what percentage of that time is made up by these calls? 
Comment 12 Frederic Fusier CLA 2005-05-07 14:27:41 EDT
Fixed and released in HEAD.

Thanks Dan for the patch which looks so good that I've released as this.
All JDT/Core and JDT/UI pass with it.

I'll add specific performance test cases if time permit.
Comment 13 Maxime Daniel CLA 2005-05-12 03:31:51 EDT
Verified for 3.1 M7 using build I20050509-2010 + jdt.core HEAD (the code shows
the additions described in the bug - no performance test run though).