我重寫了你的代碼,我真的可以運行和測試,並以下面的代碼結束。這很粗糙,但適用於我,我會把我的工作放在上面。如果出現與您的實際行爲不符的情況,請通過它。
private static final int SAMPLE_RATE = 1;
public static void main(String[] args) {
long time = System.currentTimeMillis();
Calendar logged_time = Calendar.getInstance();
Format dateFormat = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss");
try (BufferedWriter writer = Files.newBufferedWriter(Paths.get("out.txt"), StandardCharsets.UTF_8)) {
for (int i = 0; i < 100000; i++) {
// print the line
writer.write(i + ", " + dateFormat.format(logged_time.getTime()));
writer.newLine();
// add the sample rate to calculate next date/time
logged_time.add(Calendar.SECOND, SAMPLE_RATE);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
System.out.println(System.currentTimeMillis() - time + " ms");
}
當我在我的機器上運行這個時,我平均得到1000毫秒。
簡單地改變
dateFormat.format(logged_time.getTime())
到
dateFormat.format(logged_time)
導致了平均730毫秒。您無需每次都製作新的對象Date
。
但我們可以做得更好!有重複的工作lot - 我們不必一次又一次地格式化整個日期。讓我們緩存大部分格式化的日期,並只檢查當秒溢出時是否需要重新格式化它:
private static final int SAMPLE_RATE = 1;
public static void main(String[] args) {
long time = System.currentTimeMillis();
Calendar logged_time = Calendar.getInstance();
Format dateFormatNoSecs = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:");
Format dateFormatSecs = FastDateFormat.getInstance("ss");
String lastFormattedDateNoSecs = dateFormatNoSecs.format(logged_time);
int lastSecs = logged_time.get(Calendar.SECOND);
try (BufferedWriter writer = Files.newBufferedWriter(Paths.get("out.txt"), StandardCharsets.UTF_8)) {
for (int i = 0; i < 100000; i++) {
int secs = logged_time.get(Calendar.SECOND);
if (secs < lastSecs) {
// at least minutes changed, we need to reformat it
lastFormattedDateNoSecs = dateFormatNoSecs.format(logged_time);
}
// print the line
writer.write(i + ", " + lastFormattedDateNoSecs + dateFormatSecs.format(logged_time));
writer.newLine();
// add the sample rate to calculate next date/time
logged_time.add(Calendar.SECOND, SAMPLE_RATE);
lastSecs = secs;
}
} catch (IOException e) {
throw new RuntimeException(e);
}
System.out.println(System.currentTimeMillis() - time + " ms");
}
610毫秒。
最後微優化:自定義手動格式化程序秒。奇怪的是,DecimalFormat
對於秒格式化要比FastDateFormat
慢。但是,一個簡單的開關是最快的:
public class TwoDigitIntegerFormatter {
public static String format(int number) {
assert (number >= 0) && (number <= 99);
switch (number) {
case 0: return "00";
case 1: return "01";
case 2: return "02";
case 3: return "03";
case 4: return "04";
case 5: return "05";
case 6: return "06";
case 7: return "07";
case 8: return "08";
case 9: return "09";
default: return String.valueOf(number);
}
}
}
我們可以手動保持第二計數,太:
private static final int SAMPLE_RATE = 1;
public static void main(String[] args) {
long time = System.currentTimeMillis();
Calendar logged_time = Calendar.getInstance();
Format dateFormatNoSecs = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:");
String lastFormattedDateNoSecs = dateFormatNoSecs.format(logged_time);
int secs = logged_time.get(Calendar.SECOND);
try (BufferedWriter writer = Files.newBufferedWriter(Paths.get("out.txt"), StandardCharsets.UTF_8)) {
for (int i = 0; i < 100000; i++) {
if (secs > 59) {
// at least minutes changed, we need to reformat it
lastFormattedDateNoSecs = dateFormatNoSecs.format(logged_time);
secs %= 60;
}
writer.write(i + ", " + lastFormattedDateNoSecs + TwoDigitIntegerFormatter.format(secs));
writer.newLine();
// add the sample rate to calculate next date/time
logged_time.add(Calendar.SECOND, SAMPLE_RATE);
secs += SAMPLE_RATE;
}
} catch (IOException e) {
throw new RuntimeException(e);
}
System.out.println(System.currentTimeMillis() - time);
}
510毫秒。即使你的代碼不完全一樣,你也可以使用這個解決方案的想法來幫助你自己。
感謝您的回覆。藍牙通信實際上比較快,因爲我只是每行傳輸幾個字節。我還研究了一些解決方案,這些數據在數據進入時獨自坐在一個asynctask中,然後放在一起。但是,我發現我以這種方式快速耗盡內存,因爲我最終得到了一些數據副本 – Brian
只是要確定 - 您確定格式化是問題而不是I/O?你有沒有分析過它,並發現大部分時間都花在'format()'上? –
您是否嘗試過使用StringBuilder追加所有數據並僅打印/傳輸數據一次? – Mikel