したがって、file.io は、何度も実行すると非常に高価になります...私のスクリーン ショットと元のコードに見られるように、getFileContentsAsList
file.io 呼び出しを含む はかなりの回数 (18.425 回) 呼び出されます。VisualVM は、このようなボトルネックを指摘するツールの真の逸品です!
パフォーマンスを改善するためのさまざまな方法を検討した結果、file.io の呼び出しをできるだけ少なくすることがおそらく最善の方法であることに気づきました。そこで、プライベートな静的変数を使用してファイルの内容を保持し、静的イニシャライザーでファイルが書き込まれるときにのみ file.io を実行することにしました。私のアプリケーションは (幸いなことに) 過剰な書き込み (ただし過剰な読み取り) を行っていないため、アプリケーションのパフォーマンスが大幅に向上します。
getFileContentsAsList
メソッドを含むクラス全体のソースは次のとおりです。そのメソッドのスナップショットを撮ったところ、現在は 57.2 ミリ秒 (3116 ミリ秒から短縮) で実行されています。また、これは私の最長実行方法であり、現在では 4 番目に実行時間の長い方法です。合計 3812.9 ミリ秒実行された元のスクリーンショットのメソッドとは対照的に、実行時間の長い上位 5 つのメソッドは合計 498.8 ミリ秒実行されます。これは、約 85% [100 * (498.8 - 3812.9) / 3812.9] の減少率です。
package com.mbc.receiptprinter.util;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import org.apache.commons.io.FileUtils;
import com.mbc.receiptprinter.constant.FileDelimiters;
import com.mbc.receiptprinter.constant.FilePaths;
/*
* Various File utility functions. This class uses the Apache Commons FileUtils class.
*/
public class ReceiptPrinterFileUtils {
private static Map<String, String> fileContents = new HashMap<String, String>();
private static Map<String, Boolean> fileHasBeenUpdated = new HashMap<String, Boolean>();
static {
for (FilePaths fp : FilePaths.values()) {
File f = new File(fp.getPath());
try {
FileUtils.touch(f);
fileHasBeenUpdated.put(fp.getPath(), false);
fileContents.put(fp.getPath(), FileUtils.readFileToString(f));
} catch (IOException e) {
ReceiptPrinterLogger.logMessage(ReceiptPrinterFileUtils.class,
Level.SEVERE,
"IOException while performing FileUtils.touch in static block of ReceiptPrinterFileUtils", e);
}
}
}
public static String getFileContents(String filePath) throws IOException {
if (ReceiptPrinterStringUtils.isNullOrEmpty(filePath)) throw new IllegalArgumentException("File path must not be null or empty");
File f = new File(filePath);
if (fileHasBeenUpdated.get(filePath)) {
fileContents.put(filePath, FileUtils.readFileToString(f));
fileHasBeenUpdated.put(filePath, false);
}
return fileContents.get(filePath);
}
public static List<String> convertFileContentsToList(String fileContents) {
List<String> records = new ArrayList<String>();
if (fileContents.contains(FileDelimiters.RECORD)) {
records = Arrays.asList(fileContents.split(FileDelimiters.RECORD));
}
return records;
}
public static void writeStringToFile(String filePath, String data) throws IOException {
fileHasBeenUpdated.put(filePath, true);
FileUtils.writeStringToFile(new File(filePath), data);
}
public static void writeStringToFile(String filePath, String data, boolean append) throws IOException {
fileHasBeenUpdated.put(filePath, true);
FileUtils.writeStringToFile(new File(filePath), data, append);
}
}