This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 268292 - 'Heavy' CPU-intensive implementation of CachingArchiveProvider.toURI()
Summary: 'Heavy' CPU-intensive implementation of CachingArchiveProvider.toURI()
Status: CLOSED INVALID
Alias: None
Product: java
Classification: Unclassified
Component: Platform (show other bugs)
Version: Dev
Hardware: PC Windows 7
: P3 normal with 1 vote (vote)
Assignee: Tomas Zezula
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-09-30 17:52 UTC by NukemBy
Modified: 2017-11-27 17:09 UTC (History)
1 user (show)

See Also:
Issue Type: DEFECT
Exception Reporter:


Attachments
CachingArchiveProvider.toURI.jpg (187.12 KB, image/jpeg)
2016-09-30 17:52 UTC, NukemBy
Details

Note You need to log in before you can comment on or make changes to this bug.
Description NukemBy 2016-09-30 17:52:10 UTC
Created attachment 162293 [details]
CachingArchiveProvider.toURI.jpg

I came to this issue after fixing via a 'dirty hack' file access performance issue mentioned here: "Slow and Weird auto-suggest for Exception class names in New Breakpoint dialog" https://netbeans.org/bugzilla/show_bug.cgi?id=250470.

Selfprofiler shows that now 5% of total time (860ms / 15800ms) originates in that 'simple' function (See attached screenshot):

    @NonNull
    private static URI toURI (@NonNull final URL url) {
        try {
            return url.toURI();
        } catch (URISyntaxException ex) {
            throw new IllegalArgumentException(ex);
        }
    }

    Most probably it is called very frequently. The reason is here:

    public Iterable<JavaFileObject> ProxyFileManager.list(Location l, String packageName, Set<JavaFileObject.Kind> kinds, final boolean recurse) throws IOException {
        checkSingleOwnerThread();
        try {
            final JavaFileManager[] fms = getFileManagers (l);
            List<Iterable<JavaFileObject>> iterables = new ArrayList<>(fms.length);
            for (JavaFileManager fm : fms) {
                iterables.add(fm.list(l, packageName, kinds, recurse));
            }

    ->

    @Override
    public Iterable<JavaFileObject> CachingFileManager.list( Location l, String packageName, Set<JavaFileObject.Kind> kinds, boolean recursive ) {
         for(ClassPath.Entry entry : this.cp.entries()) {
            try {
                Archive archive = provider.getArchive( entry.getURL(), cacheFile );

    ->

    @CheckForNull
    public Archive CachingArchiveProvider.getArchive(@NonNull final URL root, final boolean cacheFile)  {
        final URI rootURI = toURI(root);


    Where 'ClassPath.Entry' is declared as 

        public final class Entry {
            private final URL url;

So .. it has sense to store 'url' as 'URI' at first place to avoid numerous conversion or ... change algorithm to reduce number of iterations (the later one is more efficient I guess, both - will drastically improve performance :)). 

Call stack to this place is:

"Code Completion"
	at org.netbeans.modules.java.source.parsing.CachingArchiveProvider.toURI(CachingArchiveProvider.java:354)
	at org.netbeans.modules.java.source.parsing.CachingArchiveProvider.getArchive(CachingArchiveProvider.java:129)
	at org.netbeans.modules.java.source.parsing.CachingFileManager.list(CachingFileManager.java:128)
	at org.netbeans.modules.java.source.parsing.ProxyFileManager.list(ProxyFileManager.java:153)
	at com.sun.tools.javac.code.ClassFinder.scanPlatformPath(ClassFinder.java:616)
	at com.sun.tools.javac.code.ClassFinder.fillIn(ClassFinder.java:537)
	at com.sun.tools.javac.code.ClassFinder.complete(ClassFinder.java:305)
	at com.sun.tools.javac.code.ClassFinder.access$000(ClassFinder.java:75)
	at com.sun.tools.javac.code.ClassFinder$1.complete(ClassFinder.java:169)
	at com.sun.tools.javac.code.Symbol.complete(Symbol.java:591)
	at com.sun.tools.javac.code.ClassFinder.completeOwners(ClassFinder.java:317)
	at com.sun.tools.javac.code.ClassFinder.complete(ClassFinder.java:289)
	at com.sun.tools.javac.code.ClassFinder.access$000(ClassFinder.java:75)
	at com.sun.tools.javac.code.ClassFinder$1.complete(ClassFinder.java:169)
	at com.sun.tools.javac.code.Symbol.complete(Symbol.java:591)
	at com.sun.tools.javac.code.Symbol$ClassSymbol.complete(Symbol.java:1106)
	at com.sun.tools.javac.model.JavacElements.nameToSymbol(JavacElements.java:165)
	at com.sun.tools.javac.model.JavacElements.getTypeElement(JavacElements.java:105)
	at com.sun.tools.javac.model.JavacElements.getTypeElement(JavacElements.java:65)
	at org.netbeans.modules.debugger.jpda.ui.completion.ExceptionCompletionProvider$CompletionUserTask.run(ExceptionCompletionProvider.java:146)
	at org.netbeans.modules.debugger.jpda.ui.completion.ExceptionCompletionProvider$CompletionUserTask.run(ExceptionCompletionProvider.java:126)
	at org.netbeans.modules.java.source.parsing.MimeTask.run(MimeTask.java:83)
	at org.netbeans.modules.parsing.impl.TaskProcessor.callUserTask(TaskProcessor.java:609)
	at org.netbeans.modules.parsing.api.ParserManager$MimeTaskAction.run(ParserManager.java:380)
	at org.netbeans.modules.parsing.api.ParserManager$MimeTaskAction.run(ParserManager.java:363)
	at org.netbeans.modules.parsing.impl.TaskProcessor$2.call(TaskProcessor.java:204)
	at org.netbeans.modules.parsing.impl.TaskProcessor$2.call(TaskProcessor.java:201)
	at org.netbeans.modules.masterfs.filebasedfs.utils.FileChangedManager.priorityIO(FileChangedManager.java:176)
	at org.netbeans.modules.masterfs.providers.ProvidedExtensions.priorityIO(ProvidedExtensions.java:360)
	at org.netbeans.modules.parsing.nb.DataObjectEnvFactory.runPriorityIO(DataObjectEnvFactory.java:141)
	at org.netbeans.modules.parsing.impl.Utilities.runPriorityIO(Utilities.java:88)
	at org.netbeans.modules.parsing.impl.TaskProcessor.runUserTask(TaskProcessor.java:201)
	at org.netbeans.modules.parsing.api.ParserManager.parse(ParserManager.java:334)
	at org.netbeans.api.java.source.JavaSource.runUserActionTaskImpl(JavaSource.java:415)
	at org.netbeans.api.java.source.JavaSource.runUserActionTask(JavaSource.java:407)
	at org.netbeans.modules.debugger.jpda.ui.completion.ExceptionCompletionProvider$1.query(ExceptionCompletionProvider.java:114)
	at org.netbeans.spi.editor.completion.support.AsyncCompletionTask.run(AsyncCompletionTask.java:223)
	at org.openide.util.RequestProcessor$Task.run(RequestProcessor.java:1443)
	at org.netbeans.modules.openide.util.GlobalLookup.execute(GlobalLookup.java:68)
	at org.openide.util.lookup.Lookups.executeWith(Lookups.java:303)
	at org.openide.util.RequestProcessor$Processor.run(RequestProcessor.java:2058)


Note: nearby there is more interesting function, but i do not known when it may get call ...
    I see 6 conversion here: File -> toURI() -> toURL() + root.toExternalForm() + format() + toURI()
    Most probably it will also be a huge CPU consumer when 

    @NonNull
    private static URI toURI(@NonNull final Pair<File,String> path) {
        try {
            final URL root = FileUtil.getArchiveRoot(BaseUtilities.toURI(path.first()).toURL());
            return new URI(String.format(
                "%s%s", //NOI18N
                root.toExternalForm(),
                PATH_RT_JAR_IN_CT_SYM));
        } catch (MalformedURLException | URISyntaxException e) {
            throw new IllegalArgumentException(e);
        }
    }
Comment 1 t_gergely 2017-06-02 13:59:30 UTC
(In reply to NukemBy from comment #0)
 
> I came to this issue after fixing via a 'dirty hack' file access performance
> issue mentioned here: "Slow and Weird auto-suggest for Exception class names
> in New Breakpoint dialog"
> https://netbeans.org/bugzilla/show_bug.cgi?id=250470.

Would you share that hack please? That broken org.netbeans.modules.java.source.parsing... algorithm got unbearably slow for me in Windows 7.
Comment 2 NukemBy 2017-06-06 13:02:42 UTC
I can't remember which particular hack I've mentioned and I afraid it does not matter much - many of them (hacks) are needed. 

All-in-one 'patch' with my attempts to fix various file-related performance issues you can find as attachment here https://netbeans.org/bugzilla/show_bug.cgi?id=268744. But after that I've got many other performance issues - that time in JS part. My patches to this part are attached here https://netbeans.org/bugzilla/show_bug.cgi?id=268745.

Finally I quit trying to improve performance in NetBeans - it is the effort which will never end and with rather doubtful result. Most of my current work-related things can be fulfilled with free IntelliJ IDEA Community Edition, and it is lightning-fast in comparison to NetBeans. IMHO NetBeans requires major code refactoring, what is very-very resource consuming and most probably team just do not have enough capacity for that.
Comment 3 t_gergely 2017-06-07 10:24:09 UTC
(In reply to NukemBy from comment #2)

Thank you. I agree with you. Alas, I must give up fixing NetBeans for now, too. I couldn't find adequate documentation, e.g. almost nothing about caching. Nb-javac is a separate project and I couldn't even find versioning tags to associate with recent NetBeans versions.
Comment 4 Christian Lenz 2017-11-27 17:08:46 UTC
I will close it, because it will handled now at the JIRA board: https://issues.apache.org/jira/browse/NETBEANS-183. Please feel free to change the state of the ticket.
Comment 5 Christian Lenz 2017-11-27 17:09:15 UTC
Please handle everything there now.