[jcifs] Performance improvement
Johan Hägre
johan at hagre.net
Thu Dec 20 16:26:55 MST 2012
Hello,
I have recently started using jcifs-1.3.17 to add support for direct
access to SMB shares in an old web application I have used for years, it
used to read the files from the local filesystem. When I replaced the
regular File objects with SmbFile objects and started the application
the performance was horrible, what used to take a second took several
minutes (loading the start page). After a week or so of investigating
the problem I have found the cause, it seems that the equals() and
hashCode() methods of SmbFile are quite slow. My application caches
folder settings in a HashMap using the SmbFile objects as keys so it was
heavily affected by this. By overriding the mentioned methods the
performance is about the same as when using the local file system, my
implementation looks like this.
@Override
public int hashCode() {
return getPath().hashCode();
}
@Override
public boolean equals(Object pObj) {
if (pObj == null) {
return false;
}
try {
return getPath().equals(((SmbFileImpl) pObj).getPath());
} catch (ClassCastException e) {
return false;
}
}
This implementation is not as fault tolerant for errors in the URL as
the original one so I have also added a check to the end of each
constructor to make sure the URLs are OK.
private void verifyPath() throws SmbException {
String vPath = getPath();
if (!vPath.toLowerCase().startsWith("smb://")) {
throw new SMBPathFaultException("An SMB URL must start with
'smb://'");
}
if (vPath.indexOf("//", "smb://".length()) != -1) {
throw new SMBPathFaultException("An SMB URL must not
contain '//' except from in the beginning");
}
if (isDirectory()) {
if (!vPath.endsWith("/")) {
throw new SMBPathFaultException("A directory path must
end with a '/'");
}
} else {
if (vPath.endsWith("/")) {
throw new SMBPathFaultException("A regular file path
must not end with a '/'");
}
}
}
Now to my question, the code seems to work OK and the performance is
clearly a lot better (I measured the equals method to take about 30ms on
my laptop before, now it's less than 1ms). But since I'm no expert on
either the jcifs code or the SMB protocol it would be great if someone
with more knowledge took a look at the problem and either solved it in a
better way or if my solution is OK simply included my code in a coming
release.
Regards
Johan Hägre
More information about the jCIFS
mailing list