2014-07-15 4 views
3

디렉토리에서 중복 (md5로) 파일을 효율적으로 결정하고 ": 고유"파일과 ": 기타"파일로 된 맵 콜렉션을 만드는 방법을 찾고 있습니다 . 아래 코드는 약 46 초 (45948ms) 내에 2919 개의 파일에서이를 수행 할 수 있습니다.Clojure의 효율적인 중복 검사기

이 코드는 작동하지만 더 빠른 방법이 필요합니다. 코드를 변경하여 성능을 조금 더 높이려면 어떻게해야합니까?

(def extensions [".mp3" ".wav" ".mp4" ".flac" ".aac"]) 

(defn valid? [file] 
    "returns true when the file is not a directory and ends in one of the specified extensions" 
    (and (not (.isDirectory file)) 
     (some true? (map #(.endsWith (.getName file) %) extensions)))) 

(defn file->file+hash [file] 
    "returns a map of the filepath and the files md5" 
    {:hash (d/md5 file) :path (.getAbsolutePath file)}) 

(defn split [[x & more]] 
    {:unique (:path x) :other (vec (map :path more))}) 

(defn get-dictionary [file-directory] 
    "returns a map of maps, each of which contain a ':unique' file and a vector of ':other' files" 
    (let [files (filter valid? (file-seq (f/file file-directory)))] 
    (map split (vals (group-by :hash (pmap file->file+hash files)))))) 

(def location "/home/matt/Music/Playlists") 
(prn (str "Files: " (count (file-seq (f/file location))))) 
(time (get-dictionary location)) 

"Files: 2919" 
"Elapsed time: 45948.444212 msecs" 
+0

"d/md5"는 clj-digest에서 가져옵니다. "d"는 별칭입니다 –

+4

빠른 해시 알고리즘을 사용합니까? CRC - 예를 들어 MD5를 더 잘 보완해야합니다. 그 외에도 병목 현상이 디스크 읽기가 될 것으로 짐작하고 있습니다. – dsm

+0

코드의 프로파일을 작성 했으므로 코드의 어떤 부분이 느린 지 알 수 있습니까? 99 %의 시간이 디스크가 회전하기를 기다리고 있다면 마이크로 최적화를 권장하는 것은 어리석은 일입니다. – zck

답변

0

해시 대신 파일 크기와 같은 초기 비교를 시도해 볼 수 있습니다. 대부분의 파일이 고유하다고 예상하면 모든 파일에 대해 해시를 계산하는 데 많은 시간을 절약 할 수 있습니다.