2014-08-31 28 views
4

我在CodeEval上做了一些任務。基本上,任務非常簡單:「打印出從文件中讀取的所有整數的總和」。如何從性能問題的文件中讀取整數?

我的解決方案如下:

import java.io.File; 
import java.io.IOException; 
import java.io.BufferedReader; 
import java.io.FileReader; 

public class SumIntegersFromFile { 

    public static void main(String args[]) throws IOException{ 

     File file = new File(args[0]); 
     BufferedReader br = new BufferedReader(new FileReader(file)); 
     String line; 
     int i=0; 
     while((line=br.readLine())!=null){ 
      int k = Integer.parseInt(line); 
      i+=k; 
     } 
     br.close(); 
     System.out.println(i); 
    } 
} 

但有人告訴我,這個解決方案不是從性能上看最佳。

該代碼基於問題Best way to read a text file中的建議。唯一的區別是我讀的是整數而不是字符串。

從Java中的文件中讀取整數的性能最有效的方法是什麼?

+3

「我從35中只得到29.352」是什麼意思? – BitNinja 2014-08-31 20:11:27

+9

這個問題似乎是無關緊要的,因爲它是關於改進工作代碼。嘗試在[codereview.se]上發佈。 – Keppil 2014-08-31 20:14:17

+0

@BitNinja我的意思是分數,最高分是35,我得到29.352 – 2014-08-31 20:16:57

回答

1

除非您明確告知否則,否則您不應該認爲總數適合int。嘗試將i的類型更改爲long或甚至BigInteger,然後查看這對您的分數是否有所影響。

您可以嘗試使用k(並使用Long.parseLong(line))。這將取決於問題的確切措詞,但個別值也可能超過int的限制。

還有一件事......這個問題,正如你說過的,只是說你應該總結所有的整數。這留下了可能性,將有不是整數的行,在這種情況下,你應該跳過它們,而不是拋出一個NumberFormatException(這是你的代碼現在會做的)。

(可能你已經被告知,這是每行一個條目...)

但是,如果你想擠進的性能每一點出來,你需要閱讀文件爲二進制,而不是線按線路:將每條線路變成String太貴了。有關如何操作的詳細信息,請參閱this question on summing integers from a text file

+0

謝謝你的回答。我正確地解決了這個問題,問題在於它沒有那麼優化。完整的描述在這裏:https://www.codeeval.com/open_challenges/24/ – 2014-08-31 20:56:02

+0

你能發佈對比分的完整分析嗎?它給你多少細節? – 2014-08-31 21:04:41

+0

是的,你可以在這裏找到它: MAX_MEMORY = 20 * 1024 * 1024#20 MB MAX_TIME = 10 * 1000#10秒 #如果提交花費超過10秒 #或使用超過20MB以上的內存 #的得分是0 如果memory_taken> MAX_MEMORY或TIME_TAKEN> MAX_TIME: 返回0 max_total_score = total_max [類別] memory_factor = 1 - memory_taken/MAX_MEMORY 時間因子= 1 - TIME_TAKEN/MAX_TIME 因子=(memory_factor +時間因子)/ 2 返回分數* max_total_score * factor/100 – 2014-08-31 21:08:03

1

我沒有看到你的代碼的性能錯誤。也就是說,我質疑你的程序有任何問題。

從文件或整個網絡中讀取數據的速度比操縱內存中的數據要慢幾個數量級。因此,將I/O與某些內存數據操作混合在一起的代碼的性能通常由I/O所花費的時間來控制。調整內存中的數據操作很少值得。如果I/O操作與數據操作並行發生(如果O/S執行一些預讀操作,情況將會如此),數據操作幾乎可以自由:使數據操作更快將不會減少所需的時間,因爲任何數據操作的CPU時間的減少將被等待輸入時程序阻塞的時間量的增加精確地抵消。

執行I/O並需要良好性能的程序必須減少阻塞等待I/O所花費的時間。它們的運行方式應能使它們利用硬件和操作系統提供的優化來減少阻塞量。

重要的是,在低級別,磁盤和網絡不會在每個操作的少量字節上運行。他們使用更大的數據包或塊。與操作系統交互以讀取比存儲在一個磁盤塊中更少的字節是浪費資源。程序通過緩衝它們的I/O來避免這樣做,所以程序本身將許多小I/O操作的序列變成更少但更大的操作。你正在使用BufferedReader,所以你已經這麼做了。

操作系統可能會進行一些預讀操作:如果在文件開始時要求塊中的字節,它會猜測您可能會按順序讀取文件,因此值得它也可以獲取文件的一些後續塊,預計你的程序也需要這些塊。按順序讀取文件可以提高性能。你已經這樣做了。