Bug 96058 - NLS/MessagesProperties should not call Properties.load()
Summary: NLS/MessagesProperties should not call Properties.load()
Status: RESOLVED WONTFIX
Alias: None
Product: Equinox
Classification: Eclipse Project
Component: Framework (show other bugs)
Version: 3.1   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: equinox.framework-inbox CLA
QA Contact:
URL:
Whiteboard: stalebug
Keywords: performance
Depends on:
Blocks:
 
Reported: 2005-05-19 23:31 EDT by Chris Laffra CLA
Modified: 2018-11-16 09:17 EST (History)
3 users (show)

See Also:


Attachments
JDT Preference loading its resource bundle (198.72 KB, image/jpeg)
2005-05-20 10:36 EDT, Chris Laffra CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Chris Laffra CLA 2005-05-19 23:31:16 EDT
Discovered on 3.1M7

MessageResourceBundle uses the new field-based ResourceBundle to make NLS 
resolution much faster. This is good. However, loading the properties files is 
still expensive in its current form. All time spent inside 
MessageResourceBundle.load() is actually spent inside Properties.load(). For 
14 occurences, this takes 600ms. Too much for an Eclipse startup into an empty 
perspective.

Properties.load() is very expensive. I propose the following code.
I am not sure if it covers \r\n as line delimitor. I also typed in the code in 
this text box, and did not check syntax: 

DataInputStream is = ...;
int len = is.available();
byte bytes[] = new byte[len];
is.readFully(bytes);
int start = 0;
String key;
for (int index=0; index<len; index++) {
    switch (bytes[index]) {
    case '=':
        key = new String(bytes, start, index-start-1);
        start = index + 1;
        break;
    case '\n':
        String value = new String(bytes, start, index-start-1);
        addNLSString(key, value);
        start = index + 1;
        break;
    }
Comment 1 Chris Laffra CLA 2005-05-19 23:36:40 EDT
To support UTF8, you may need to do the scanning on a String. In that case say:

    String buffer = new String(bytes);
    for (int index=0; index<len; index++) {
        switch (buffer.charAt(index)) {

Comment 2 Thomas Watson CLA 2005-05-20 08:53:40 EDT
Properties.load maybe expensive, but I caution against any change in behavior  
when loading NLS properties files.  

- Need to handle comments (lines with '#' or '!' as the first non-whitespace 
char)
- Need to handle all delemeters ('=' is common but you can use ':' and maybe 
others)
- ISO 8859-1 character encoding is used to read properties
- Need to handle line continuations
- others ... ?
Comment 3 Pascal Rapicault CLA 2005-05-20 08:59:07 EDT
I agree with Tom. I was updating the bug with similar notes.
Comment 4 Chris Laffra CLA 2005-05-20 10:35:07 EDT
Arguments taken. Discarded as unacceptable.

I just activated the Java Perspective the first time in a launch. 30% is spent 
inside Properties.load() with 8% just in jdt.PreferenceMessages. This is way 
too much. See attached screendump of Xray.

What Properties.load() does in addition to all the correct parsing is 
expensive reading. It uses BufferedReader with readLine(), and then numerous 
indexOf(), charAt(), substring, and StringBuffer.append() calls to get both 
the key and the value. Then those values are intercepted by MessageProperties 
and stored in a field (which is almost free).

We need to find a way to load the properties files faster. The way it is done 
now does not scale to applications with hundreds of plugins. 
We may need to find a way to compile them into a class file. I have code to 
parse a jar, find properties files and create binary class files for them. 
That would be a useful addition to PDE.

Note how activating the Java perspective loads the resource bundle for JDT 
preferences. Why would that be? I haven't done Window > Preferences > Java.
What about lazy loading?
Comment 5 Chris Laffra CLA 2005-05-20 10:36:56 EDT
Created attachment 21504 [details]
JDT Preference loading its resource bundle

Properties.load() uses a disproportional amount of time.
Comment 6 Pascal Rapicault CLA 2005-05-20 10:51:08 EDT
Arguments accepted. Full patch expected.
Comment 7 Jeff McAffer CLA 2005-05-24 13:12:35 EDT
Lazy loading is a good thing. There will be side-effects here because of 
verification.  That is, message loading is caused by the loading of the 
corresponding message class and that can be triggered by verification.

We can change the loading code but have to be 100% that we are not losing 
function.  People expect to be able to write standard properties files and all 
that entails.  It would be itneresting for example to look at the current 
(slow) code and see what is being done that does not need to be done.

I suggest that it is too late for 3.1.  We can consider this for 3.1.1 and 3.2
Comment 8 John Arthorne CLA 2005-05-24 16:10:30 EDT
The following .options property will tell you the wall-clock time of resource
bundle loading (using System.currentTimeMillis()):

org.eclipse.osgi/debug/messageBundles=true

By turning this on, I see most bundles load in "0" time (within the granularity
of System.currentTimeMillis()), or at most 10-15 ms per bundle. It is possible
that we could improve on the class library implementation of property file
loading, or that translations could occur at build or install time, but the
current overhead is not huge.  There are definitely optimizations that can be
explored in the next release.
Comment 9 Chris Laffra CLA 2005-05-26 22:19:38 EDT
I measured the following scenario. Start into Resource perspective with one 
project, no editors open. Start timer, then switch to Java perspective, then 
measure consumed CPU time. This is not using a profiler, I just measure 
consumed CPU time, using Windows performance counters. 

Here are the unofficial results for my laptop:

                    original   jclMax    difference
IBM J9SE 1.4.2      2,123ms    1,822ms   299ms  14% of total
Sun JRE 1.4.2_04    2,642ms    2,544ms   102ms   4% of total

In total 15 message bundles are loaded. We either load with the original 
Properties.load(InputStream) which is used by MessageProperties, or we use 
the version shipped with IBM J9 jclFoundation, whose implementation is also 
used in J2ME and has been certified there. 

Note that on Sun, 102ms/15 < 10ms on average. On IBM, 299/15 > 10ms on average.

In other words, by avoiding the more expensive way of reading in 
java.util.Properties, we can save between 4% and 14% for activating plugins.
I did not see any messages fail, trying out all Java scenarios I could come up 
with.
Comment 10 Pascal Rapicault CLA 2006-03-29 10:30:33 EST
In the development cycle, we are now in the same position than we were when this bug was first opened. Marking as 3.3 so we don't forget to look at it another time. Note though that we now need to support icu and the interaction with that are unclear.
Comment 11 DJ Houghton CLA 2007-03-27 16:47:27 EDT
Another release has arrived and we are in the same state yet again. sigh.
Comment 12 Thomas Watson CLA 2007-04-02 10:32:45 EDT
Any changes in this area I view as high risk.  We have no suitable replacement to Properties.load at this time.  Writing our own implementation at this time in the development cycle is way to risky.  If I had a 3.4 M1 target I would use that because this type of bug needs to be done early to flush out all the issues.
Comment 13 Eclipse Genie CLA 2018-11-16 04:29:38 EST
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet.

If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.

--
The automated Eclipse Genie.
Comment 14 Thomas Watson CLA 2018-11-16 09:17:58 EST
This isn't going to happen at this point.