簡體   English   中英

Java遍歷數組-優化

[英]Java looping through array - Optimization

我有一些Java代碼可以按預期的方式運行,但是即使工作只是遍歷數組,也要花一些時間(幾秒鍾)。

輸入文件是Fasta文件,如下圖所示。 我正在使用的文件是2.9Mo,還有一些其他Fasta文件可能會占用20Mo。

在此處輸入圖片說明

在代碼中,im試圖通過三連串循環遍歷它,例如:AGC TTT TCA ...等該代碼目前沒有功能,但是我想要的是將每個氨基酸附加到它的等價鹼基上。 范例:

AGC-Ser / CUG Leu / ...等

那么代碼有什么問題呢? 還有什么辦法可以做得更好? 任何優化? 遍歷整個String會花費一些時間,可能只是幾秒鍾,但是需要找到一種更好的方法來完成。

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

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

        File fastaFile;
        FileReader fastaReader;
        BufferedReader fastaBuffer = null;
        StringBuilder fastaString = new StringBuilder();

        try {
            fastaFile = new File("res/NC_017108.fna");
            fastaReader = new FileReader(fastaFile);
            fastaBuffer = new BufferedReader(fastaReader);
            String fastaDescription = fastaBuffer.readLine();
            String line = fastaBuffer.readLine();

            while (line != null) {
                fastaString.append(line);
                line = fastaBuffer.readLine();
            }

            System.out.println(fastaDescription);
            System.out.println();
            String currentFastaAcid;

            for (int i = 0; i < fastaString.length(); i+=3) {
                currentFastaAcid = fastaString.toString().substring(i, i + 3);
                System.out.println(currentFastaAcid);
            }

        } catch (NullPointerException e) {
            System.out.println(e.getMessage());
        } catch (FileNotFoundException e) {
            System.out.println(e.getMessage());
        } catch (IOException e) {
            System.out.println(e.getMessage());
        } finally {
            fastaBuffer.close();
        }

    }

}
currentFastaAcid = fastaString.toString().substring(i, i + 3);

請替換為

currentFastaAcid = fastaString.substring(i, i + 3);

每次調用StringBuilder的toString方法時,都會創建String對象的新實例。 它仍然包含所有大字符串的副本。 如果直接從StringBuilder調用子字符串,它將返回子字符串的一個小副本。 如果確實不需要,也請刪除System.out.println。

這里最大的因素是您每次都在新的String上調用子字符串。

而是直接在stringbuilder上使用子字符串

for (int i = 0; i < fastaString.length(); i+=3){
    currentFastaAcid = fastaString.substring(i, i + 3);
    System.out.println(currentFastaAcid);
}

另外,不要每次都打印currentFastaAcid,而是將其保存到列表中並在末尾打印此列表。

List<String> acids = new LinkedList<String>();

for (int i = 0; i < fastaString.length(); i+=3){
    currentFastaAcid = fastaString.substring(i, i + 3);
    acids.add(currentFastaAcid);
}

System.out.println(acids.toString());

除了調試輸出,您的主要問題肯定是,您正在創建一個新的String,並且在循環的每次迭代中都從文件中完全讀取了數據:

currentFastaAcid = fastaString.toString().substring(i, i + 3);

fastaString.toString()在每次迭代中將給出相同的結果,因此是多余的。 將其置於循環之外,您肯定會節省幾秒鍾的運行時間。

除了建議的串行代碼優化之外,我還將進行並行處理以進一步減少時間。 如果文件很大,則可以將讀取文件和處理讀取行的工作分在不同的線程中。 這樣,當一個線程正忙於從大文件讀取下一行時,另一線程可以處理讀取行並將其打印在控制台上。

如果刪除

System.out.println(currentFastaAcid);

在for循環中,您將獲得相當不錯的時間。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM