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 268026

Summary: Performance issue in BaseFileObj.getPath --> FileName.getName
Product: ide Reporter: NukemBy
Component: PerformanceAssignee: Tomas Hurka <thurka>
Status: NEW ---    
Severity: normal    
Priority: P3    
Version: Dev   
Hardware: PC   
OS: Windows 7   
Issue Type: DEFECT Exception Reporter:
Attachments: BaseFileObj.getPath --> FileName.getName

Description NukemBy 2016-09-14 15:40:10 UTC
Created attachment 162049 [details]
BaseFileObj.getPath --> FileName.getName

Please take a look onto attached screenshot of selfprofiler.

I see there is strange collaboration between BaseFileObj & FileName classes.

FileName actually stores the name as some CharSequence and each call to fileNaming.getName() results in call to CharSequence.toString(), so ... building a path of 10 elements in BaseFileObj.getPath() is actaully construction of 10 new Strings plus 10 invocations of toString(). This is pressure on both CPU and GC.

It may happen that someone wanted to implement FileNaming.appendNameTo(StringBuilder pathName), but it is not.

Anyway - current implementation is very performance unfriendly.

Below is the source code for reference

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

public class FileName implements FileNaming {

    protected FileName(final FileNaming parent, final File file, Integer theKey) {
        this.parent = parent;
        this.name = CharSequences.create(parseName(parent, file));
        this.currentName = name;

    public @Override final String getName() {
        return currentName.toString();
    }


public abstract class BaseFileObj extends FileObject {

    @Override
    public final String getPath() {
        FileNaming fileNaming = getFileName();
        Deque<String> stack = new ArrayDeque<String>();
        while (fileNaming != null) {
            stack.addFirst(fileNaming.getName());
            fileNaming = fileNaming.getParent();
        }
        String rootName = stack.removeFirst();
        if (BaseUtilities.isWindows()) {
            rootName = rootName.replace(File.separatorChar, '/');
            if(rootName.startsWith("//")) {  //NOI18N
                // UNC root like //computer/sharedFolder
                rootName += "/";  //NOI18N
            }
        }
        StringBuilder path = new StringBuilder();
        path.append(rootName);
        while (!stack.isEmpty()) {
            path.append(stack.removeFirst());
            if (!stack.isEmpty()) {
                path.append('/');  //NOI18N
            }
        }
        return path.toString();
    }