2017-05-08 49 views
2

這些文件提交給我的服務器,我試圖確定CSV是否有效,以及從CSV引用的所有圖像都存在於zip中。我必須使用所有這些信息填充Mongo數據庫,但我想在後臺執行此操作,並儘可能快地向客戶端發送響應。Nodejs:性能問題解析CSV和郵政編碼

所以我有兩個可讀流,我有三個不同的方法:

  • 解壓文件24秒發生,所以解壓+解析+ CSV是fs.exists不是一個選項。

  • 解析整個csv,保存數組中的文件名,然後使用node-unzip和pipe讀取zip需要5秒鐘。

  • 讀取csv並行讀取zip並使用共享數組來確定文件是否存在,這是最快的選項,需要4秒。

有沒有人有如何更快地做到這一點的想法?

EDIT:用於驗證的代碼是:

// lib/validator.js 

function validateParallel(csv, zip) { 
    const shared = {}; 
    return new Promise((resolve, reject) => { 
    const l = CSV_VALIDATORS.length - 1; 
    csv 
     .pipe(split()) 
     .pipe(through2(validateLine.bind({ zip, reject, n: 0, l, shared }))) 
     .on('finish',() => { 
     zip 
     .pipe(unzip.Parse()) 
     .on('entry', (entry) => { 
      delete shared[entry.path]; 
     }) 
     .on('close',() => { 
      resolve(Object.keys(shared).length === 0); 
     }); 
     }); 
    }); 
} 

// perfomance/validate.spec.js 

const zip = fs.createReadStream('./performance/imports/import.zip'); 
const csv = fs.createReadStream('./performance/imports/stress-test.csv'); 

const hrstart = process.hrtime(); 
validator 
    .validateParallel(csv, zip) 
    .then(function(isValid) { 
    console.log(`valid=${isValid}`); 
    const hrend = process.hrtime(hrstart); 
    console.info("Execution time (hr): %ds %dms", hrend[0], hrend[1]/1000000); 
}); 

ValidateLine取圖像名稱並將它推入共享對象。輸出是:

valid=true 
Execution time (hr): 4s 926.031869ms 

我簡化了代碼並刪除了錯誤管理以使其更具可讀性。

+0

應該有能力得到一個zip文件的內容,而不解壓縮整個文件,我會認爲應該更快。 – jfriend00

+0

即使文件在流中?我還沒有找到那樣的東西。 – Diego

+0

我們需要查看您的代碼。可以從流中獲取zip文件條目而不將整個zip文件保存到磁盤。 – jfriend00

回答

1

您是否還必須自行驗證圖像,或者確保其路徑存在於CSV文件中?如果是後者,你可以運行一個在壓縮文件上執行unzip -l的shell進程,該文件只打印文件名,應該很快。

+0

只要存在。但我需要將整個文件寫入磁盤。 – Diego

+0

比你的三種解決方案還要快很多,儘管它們間接地保存了文件。 我不確定您是否可以依賴zip格式,但您可能能夠從流的開頭嗅探文件名,因此您不必繼續閱讀它。 – yelsayed

+0

解決方案2和3解析內存中的zip文件而非磁盤。儘管'unzip -l'更快,我不能等待24秒來響應,但將文件直接傳輸到磁盤而不分析任何東西需要24秒。 – Diego