2012-08-09 35 views
2

我的問題是,如果.csv文件足夠大,map/zipmap步驟(如下)是否會冒着消耗太多內存的風險?我的程序的map/zipmap部分可以消耗太多內存嗎?

我有一個從clojure-csv返回的序列序列。爲清楚起見,以下步驟是故意分開的。換句話說,我將在生產代碼中結合其中一些。

; Process the .csv file 
(defn fetch-csv-data 
    "This function accepts a csv file name, and returns parsed csv data, 
    or returns nil if file is not present." 

    [csv-file] 
     (let [csv-data (ret-csv-data csv-file)] 
      csv-data)) 

(def bene-csv-inp (fetch-csv-data "benetrak_roster.csv")) 

; Pull out the columns/keys, and 
(def bene-csv-cols (map #(cstr/trim %1) (first bene-csv-inp))) 

; create the keys. 
(def bene-csv-keys (map #(keyword %1) bene-csv-cols)) 

; Make a sequence of just one of the keys: 

(def test-ssns2 (map (fn [x] (:GIC-ID x)) 
       (map #(zipmap gic-csv-keys %1) gic-csv-data))) 

謝謝。

+0

回覆:「我會在生產代碼中結合其中一些。」熱點編譯器在內聯方面非常出色,如果你只需要地圖而不是原始的CSV數據,就不需要讓代碼不那麼漂亮,只需要JVM – 2012-08-09 18:59:19

回答

4

此代碼將泄漏內存的唯一方法是因爲def s將保存惰性序列的頭部。如果用返回序列的函數替換它們,那麼實際的頭部將只存在於調用堆棧中,並通過惰性評估正確處理。

(defn bene-csv-inp [] (fetch-csv-data "benetrak_roster.csv")) 

; Pull out the columns/keys, and 
(defn bene-csv-cols [] (map #(cstr/trim %1) (first (bene-csv-inp)))) 

; create the keys. 
(defn bene-csv-keys [] (map #(keyword %1) (bene-csv-cols))) 

這是一個粗略的規則,儘管有時是有用的,與defn的替代defs當它們含有無窮序列,使他們處處調用,而不是讀(除非你真的想要一個懶惰的緩存好處序列爲多個閱讀器,並且序列只會有一個合理數量的數據讀取)。

使用函數調用而不是讀取defs在這裏,一旦熱點編譯器完成,幾乎肯定不會對運行時產生任何影響。

+0

+1,那麼就不要拘泥於你通過的懶惰seq zipmap,一切都應該沒問題。 – Alex 2012-08-09 19:09:41

+0

@ Arthur-Ulfeldt謝謝。我會取代defs;他們只是出於演示目的。 – octopusgrabbus 2012-08-09 19:33:29