這個想法來自有一次需要處理大檔案的數據資料(CSV),檔案內容有10萬行*數百欄位,在使用kotlin-csv套件讀進程式中後,就觸發了outOfMemory!,沒錯,記憶體炸啦!
//開啟輸入流 val inputStream = contentResolver.openInputStream(projectDocumentFiles.rawData.uri) //用kotlin-csv套件開啟csv檔 listLeftData = csvReader().readAll(inputStream)
仔細慢慢分析後,發現List格式非常吃記憶體,csv讀近來後通通用List<List<String>>存,雖然方便,但炸掉的話就沒搞頭啦!
所以對於這種大型資料讀取,我選擇自己做最佳化。
首先分析檔案內容,我的csv內都是儲存數字,所以我們的變數就以float Array為主要儲存方式,並且每行資料再由List來儲存,記憶體就不會吃到這麼重。
另外讀取方式也要一次讀一行,節省處理過程中的記憶體占用!
//取得輸入流 val inputStream = contentResolver.openInputStream(projectDocumentFiles.rawData.uri) //用BufferedReader讀取 val reader = BufferedReader(InputStreamReader(inputStream)) //大檔讀取,省記憶體,會自動關閉io reader.forEachLine { //切割資料 val tmpValues = it.split(",") //建立float陣列 val dataArray = FloatArray(tmpValues.size) for(value in 0 until tmpValues.size){ //將檔案中的值轉為數值 dataArray[value] = tmpValues[value].toFloat() } //將資料放進MutableList<FloatArray>中 mutableListData.add(dataArray) }
這樣實測下來,原本要吃600多MB的記憶體,可以下降至230MB左右!
雖然處理過程中複雜了一些,但一開始將資料都轉換好,也有助於之後的資料處理!~
-END-
發佈留言