none
集合物的效率何者為佳? RRS feed

  • 問題

  • 感謝各位前輩對此問題的關心及解答,先謝謝大家。

    小弟有十多份csv檔,每個檔案行數大於100萬行以上。

    光是從csv讀取進程式分析,1個檔案大約就花了10幾分鐘。

    我是使用Split(CSVTxt, vbCrLf)把每行資料放進Array

    再Split(LineStr, ",")再取得每個分隔之間的資料。

    以上並還沒開始搜尋資料就花了好久的時間........

    所以想請教,如何利用集合物的特性來修改程式碼,以增進效率。

    每行的資料如下
    2015/1/5,TXO,201501W1,8600,買權,600,600,600,600,1,650,1,640,710,660,600,

    原Code:

    Private CSVTxt As String = "" '原始CSV檔內容 Private TXOTxt As String = "" 'TXO唯一的CSV檔內容

    '...

    CSVTxt = FM.GetFileText(tempFN)

    '...

    '將CSV檔內容轉換為TXO唯一的CSV內容 Private Sub CSV_To_TXO() Dim LineTmp() As String = Split(CSVTxt, vbCrLf) Dim StrTmp() As String TXOTxt = "" For Each LineStr In LineTmp StrTmp = Split(LineStr, ",") If StrTmp.Length > 1 And StrTmp(1) = "TXO" Then TXOTxt = TXOTxt & LineStr & vbCrLf Next TXOTxt = TXOTxt.Substring(0, TXOTxt.LastIndexOf(vbCrLf)) End Sub

    小弟是希望用Dictionary相關的集合物,使用唯一Key來新增或取得Value。

    集合物是否要使用泛型?效率最快的又是那一種集合物件?

    以上並非要求前輩們給code,只求前輩們可以提供使用集合物的經驗。感謝各位!



    • 已編輯 ξ靈均ξ 2016年11月15日 上午 06:46
    2016年11月15日 上午 06:36

解答

  • 你看一下 系統管理工具 資料來源 32/64 位元。CSV 當資料庫存取是內建在作業系統內。

    在花費時間寫程式碼之前,可以看一下下面那篇,直接讓 Visual Studio IDE 介面內建的工具測效能,只要會下資料庫查詢語言就可以了。

    [VS2008] 讓伺服器總管叫出 ODBC 對話盒


    不精確的問法,就會得到隨便猜的答案;自己都不肯花時間好好描述問題,又何必期望網友會認真回答?

    • 已標示為解答 ξ靈均ξ 2016年11月21日 上午 07:26
    2016年11月20日 下午 05:14

所有回覆

  • 您好,

    可以先試看看 Parallel.ForEach 

    https://msdn.microsoft.com/zh-tw/library/dd460720(v=vs.110).aspx

    不過,資料多,全都放到 memory 上處理,就怕會 out of memory。



    亂馬客blog: http://www.dotblogs.com.tw/rainmaker/


    • 已編輯 亂馬客 2016年11月15日 上午 07:13
    2016年11月15日 上午 07:12
  • 根據您每行的資料來看:

    "每行的資料如下
    2015/1/5,TXO,201501W1,8600,買權,600,600,600,600,1,650,1,640,710,660,600,"。

     似乎是一行字串資料。

    我覺得不管使用何種集合,一定都要用split事先切割,也會浪費許多時間。

    您何不先把資料先切割後在儲存,讀檔時,就可以直接讀入各項數值資料,也不必再用split耗費時間。

    2016年11月15日 下午 12:29
  • 感謝各位前輩對此問題的關心及解答,先謝謝大家。

    小弟有十多份csv檔,每個檔案行數大於100萬行以上。

    光是從csv讀取進程式分析,1個檔案大約就花了10幾分鐘。

    我是使用Split(CSVTxt, vbCrLf)把每行資料放進Array

    再Split(LineStr, ",")再取得每個分隔之間的資料。

    以上並還沒開始搜尋資料就花了好久的時間........

    所以想請教,如何利用集合物的特性來修改程式碼,以增進效率。

    每行的資料如下
    2015/1/5,TXO,201501W1,8600,買權,600,600,600,600,1,650,1,640,710,660,600,

    原Code:

    Private CSVTxt As String = "" '原始CSV檔內容 Private TXOTxt As String = "" 'TXO唯一的CSV檔內容

    '...

    CSVTxt = FM.GetFileText(tempFN)

    '...

    '將CSV檔內容轉換為TXO唯一的CSV內容 Private Sub CSV_To_TXO() Dim LineTmp() As String = Split(CSVTxt, vbCrLf) Dim StrTmp() As String TXOTxt = "" For Each LineStr In LineTmp StrTmp = Split(LineStr, ",") If StrTmp.Length > 1 And StrTmp(1) = "TXO" Then TXOTxt = TXOTxt & LineStr & vbCrLf Next TXOTxt = TXOTxt.Substring(0, TXOTxt.LastIndexOf(vbCrLf)) End Sub

    小弟是希望用Dictionary相關的集合物,使用唯一Key來新增或取得Value。

    集合物是否要使用泛型?效率最快的又是那一種集合物件?

    以上並非要求前輩們給code,只求前輩們可以提供使用集合物的經驗。感謝各位!



    不知道我有沒有看錯, 照你這樣寫,  TXOTxt 不是會無敵長嗎 ?

    可否講述一下你整個情境的需求是甚麼? 怎麼樣的輸入會得到哪種預期的輸出 ?


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    2016年11月15日 下午 01:03
    版主
  • 檔案太大絕對快不起來。

    如果是純 csv 格式,不妨透過 odbc / oledb 當資料庫讀,至少 odbc / oledb 的 driver 在存取方面已經最佳化過了。


    不精確的問法,就會得到隨便猜的答案;自己都不肯花時間好好描述問題,又何必期望網友會認真回答?

    2016年11月15日 下午 05:02
  • 把CSV當做資料庫來處理會比當做字串處理快, 請參考:

    C# - CSV Import Export

    2016年11月16日 上午 05:42
  • 以下是當日資訊,我要的是歷史資訊。

    所以從官方取得資料csv,再應用到程式,方便找尋過去的歷史資料。

    簡單的說,選擇某交易日,再選擇某交易期別,就可顯示當天的期別歷史資料。

    歷史資料


    • 已編輯 ξ靈均ξ 2016年11月20日 下午 02:54
    2016年11月20日 下午 02:25
  • TXOTxt得確會很長!非常的長。所以會利用1年1份資料,轉寫進自訂的Class當屬性存取,並序列化。

    所以每1個檔案就得執行一次寫入集合化,最後再序列化。

    最後序列化的資料就是資料庫了。不過真的很大很大。

    但是要使用何種集合物比較適合呢?


    • 已編輯 ξ靈均ξ 2016年11月20日 下午 03:00
    2016年11月20日 下午 02:28
  • 小弟沒Access軟體可當資料庫運用,也不希望筆電安裝SQL Server,會有效率及安全性的問題。(可能是我想太多了)

    所以只好用集合物件當資料庫運用了!

    2016年11月20日 下午 02:30
  • 這Split是首次性工作,當字串轉成集合物的資料,我會把集合物放在自訂的Class當屬性,再序列化成檔案,方便下載開啟軟體直接載入.

    但是要使用何種集合物會比較適合呢?

    • 已編輯 ξ靈均ξ 2016年11月20日 下午 02:34
    2016年11月20日 下午 02:33
  • 我會研究一下。感謝您的回覆!
    2016年11月20日 下午 02:33
  • 真的!只是希望能多快就多快。

    所以何種集合物比較適合呢?

    2016年11月20日 下午 02:36
  • 對不起各位,文詞有些許誤會,是我的表達有問題。

    我希望的是,Split後的資料,要使用何種集合物件存取,會比較有效率。

    資料的數量真的不算少。所有csv檔的總檔案大小,總合大約615MB的純文字檔。

    2016年11月20日 下午 02:46
  • 記憶體不足是很可怕的!不過我會學習,並試著應用看看。感謝您的回覆!
    2016年11月20日 下午 02:47
  • 小弟沒有資料庫的軟體可供應用,也沒有Office。

    而且CSV是原始來源,總是要先處理過才能運用。Splic就是處理的過程吧。

    或是大哥有其他辨法可以直接由程式取得CSV的片段資料,或搜尋資料?


    • 已編輯 ξ靈均ξ 2016年11月20日 下午 02:52
    2016年11月20日 下午 02:50
  • TXOTxt得確會很長!非常的長。所以會利用1年1份資料,轉寫進自訂的Class當屬性存取,並序列化。

    所以每1年就得執行一次寫入集合化再序列化。

    最後序列化的資料就是資料庫了。不過真的很大很大。

    但是要使用何種集合物比較適合呢?

    所以你這個無敵長的 TXOTxt 又還會經過分割的動作 ? 如果是, 那這個重複的動作就可以省下來.

    補充: 因為你的需求我還沒搞得很清楚, 不過就目前的內容來看, 這可以改進效率的點非常多, 絕不僅僅只有集合怎麼用而已


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。


    2016年11月20日 下午 02:51
    版主
  • 補充: 因為你的需求我還沒搞得很清楚, 不過就目前的內容來看, 這可以改進效率的點非常多, 絕不僅僅只有集合怎麼用而已


    我希望的是,Split後的資料,要使用何種集合物件存取,會比較有效率。
    2016年11月20日 下午 02:58
  • 補充: 因為你的需求我還沒搞得很清楚, 不過就目前的內容來看, 這可以改進效率的點非常多, 絕不僅僅只有集合怎麼用而已


    我希望的是,Split後的資料,要使用何種集合物件存取,會比較有效率。

    你的效率全都耗在讀取和轉換, 後面的集合物件其實影響搞不好是最小的

    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    2016年11月20日 下午 03:14
    版主
  • 你看一下 系統管理工具 資料來源 32/64 位元。CSV 當資料庫存取是內建在作業系統內。

    在花費時間寫程式碼之前,可以看一下下面那篇,直接讓 Visual Studio IDE 介面內建的工具測效能,只要會下資料庫查詢語言就可以了。

    [VS2008] 讓伺服器總管叫出 ODBC 對話盒


    不精確的問法,就會得到隨便猜的答案;自己都不肯花時間好好描述問題,又何必期望網友會認真回答?

    • 已標示為解答 ξ靈均ξ 2016年11月21日 上午 07:26
    2016年11月20日 下午 05:14
  • 你看一下 系統管理工具 資料來源 32/64 位元。CSV 當資料庫存取是內建在作業系統內。

    在花費時間寫程式碼之前,可以看一下下面那篇,直接讓 Visual Studio IDE 介面內建的工具測效能,只要會下資料庫查詢語言就可以了。

    [VS2008] 讓伺服器總管叫出 ODBC 對話盒


    不精確的問法,就會得到隨便猜的答案;自己都不肯花時間好好描述問題,又何必期望網友會認真回答?

    這是很好的解決方案,可行!太好了!

    雖然資料表一次只能建一個(檔案超多的)!不過還是可以免去Splic的時間,直接搜尋CSV的檔案內容!不用集合物了!


    • 已編輯 ξ靈均ξ 2016年11月21日 上午 07:27
    2016年11月21日 上午 07:26
  • csv 當資料庫的架構是以目錄為資料庫,每個目錄下可以有多個 csv ,每個 csv 就是一個資料表。

    csv 如果沒有建 schema.ini ,也可以用,只是自動辨識的格式可能不正確。


    不精確的問法,就會得到隨便猜的答案;自己都不肯花時間好好描述問題,又何必期望網友會認真回答?

    2016年11月21日 下午 03:10