Reputation: 101
I'm trying to optimise my code; it reads files in a specific folder and shows them in windows, then enables further work with them. Everything is working as intended, but when there are a lot of files in the folder (like 100+), loading the content is really lagging.
Can anybody give me advise on how to optimise this function?
private void ReloadScanFiles() {
if (gsfCurRow != null) {
ArrayList<FileInfo> newTreeFileInfoList = new ArrayList<FileInfo>();
ArrayList<FileInfo> addTreeFileInfoList = new ArrayList<FileInfo>();
ArrayList<String> delTreeFileNameList = new ArrayList<String>();
File folder = new File(gsfCurRow.DOC_SOURCE_PATH);
FileFilter fileFilter = new FileFilter() {
public boolean accept(File file) {
return !file.isDirectory() && !file.isHidden();
}
};
/*
FilenameFilter fileFilter = new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.toLowerCase().endsWith(".pdf") ||
name.toLowerCase().endsWith(".jpeg") ||
name.toLowerCase().endsWith(".jpg") ||
name.toLowerCase().endsWith(".tiff") ||
name.toLowerCase().endsWith(".txt");
}
};
*/
File[] listOfFiles = folder.listFiles(fileFilter);
for (int i = 0; i < listOfFiles.length; i++){
FileInfo fileInfo = new FileInfo();
fileInfo.Name = listOfFiles[i].getName();
//fileInfo.Length = (long) listOfFiles[i].length();
fileInfo.LastModified = (long) listOfFiles[i].lastModified(); //Long.parseLong("473", 10);
newTreeFileInfoList.add(fileInfo);
}
//add new items
for (FileInfo fileInfo: newTreeFileInfoList){
boolean existsItem = false;
if (actTreeFileInfoList != null){
for (FileInfo fileInfo1: actTreeFileInfoList){
if (fileInfo.Name.equals(fileInfo1.Name)) {
existsItem = true;
break;
}
}
}
if (!existsItem) {
addTreeFileInfoList.add(fileInfo);
}
}
//delete non existing items
if (actTreeFileInfoList != null){
for (FileInfo fileInfo: actTreeFileInfoList){
boolean existsItem = false;
for (FileInfo fileInfo1: newTreeFileInfoList){
if (fileInfo.Name.equals(fileInfo1.Name)) {
existsItem = true;
break;
}
}
if (!existsItem) {
delTreeFileNameList.add(fileInfo.Name);
}
}
}
actTreeFileInfoList = newTreeFileInfoList;
//add items to tree
for (FileInfo fileInfo: addTreeFileInfoList){
TreeItem item = new TreeItem(tv, SWT.NONE);
//item.setText(new String[] {fileInfo.Name, Long.toString(fileInfo.Length), df.format(fileInfo.LastModified)});
item.setText(new String[] {fileInfo.Name, null, df.format(fileInfo.LastModified)});
fileCount ++;
}
//delete item from tree
//update locked by
TreeItem [] items = tv.getItems();
for (TreeItem item: items){
//delete
if (delTreeFileNameList.contains(item.getText())) {
if (item.getChecked()) {
checkedFileCount --;
}
fileCount --;
item.dispose();
}
//update
if (!item.isDisposed()){
Integer lock_idusr = null;
try {
lock_idusr = db.FileLockedBy(gsfCurRow.DOC_SOURCE_ID, item.getText());
} catch (SQLException e) {
e.printStackTrace();
}
if ((lock_idusr != null) && (!lock_idusr.equals(idusr))){
try {
item.setText(3, db.GetOpid(lock_idusr));
} catch (SQLException e) {
e.printStackTrace();
}
Color color = new Color(display,180, 0, 0);
item.setForeground(color);
item.setChecked(false);
}
else{
item.setText(3, "");
Color color = new Color(display,0, 0, 0);
item.setForeground(color);
}
}
}
BtnDocAssignEnabled();
GenerateTreeStatusText();
}
}
Upvotes: 0
Views: 118
Reputation: 5459
The most obvious error you've done is this:
for (FileInfo fileInfo: newTreeFileInfoList){
boolean existsItem = false;
if (actTreeFileInfoList != null){
for (FileInfo fileInfo1: actTreeFileInfoList){
if (fileInfo.Name.equals(fileInfo1.Name)) {
existsItem = true;
break;
}
}
}
if (!existsItem) {
addTreeFileInfoList.add(fileInfo);
}
}
For every new element you iterate over the whole list of old entries to check if it's already in the list or not. With 100 new files this will result into 5050 iterations. Instead of an ArrayList you might consider using a Map with the filename as key. Your check would then look like this:
for (FileInfo fileInfo: newTreeFileInfoList){
if (!actTreeFileInfoMap.containsKey(fileInfo.Name)) {
actTreeFileInfoMap.put(fileInfo.Name, fileInfo);
}
}
If the actual fileinfo in the Map doesn't matter, you can skip the whole check and put the new fileInfo into the Map instead. This would lead to the replacement of the previously added one with the newly added one.
Upvotes: 2