2016-06-16 21 views
6

Tôi muốn tìm phần tử khớp đầu tiên trong danh sách vô hạn trong Haskell.Bộ lọc song song danh sách vô hạn trong Haskell

Mã này đang làm việc:

findPassword passwordHash = (head . filter (checkPassword passwordHash)) allStrings 

checkPassword thực sự là dài (vì đó là một băm SHA1)

checkPassword hash string = (sha1 string) == hash 

allStrings chỉ là danh sách của tất cả các chuỗi có thể:

allStrings = [ c : s | s <- "" : allStrings, c <- ['a'..'z'] ++ ['0'..'9'] ] 

Tôi muốn mã này được chạy song song nhưng nếu tôi thay thế bộ lọc theo parFilter:

import qualified Control.Parallel.Strategies as S 
parFilter p = S.withStrategy (S.evalBuffer 1000 S.rseq) . filter p 

Nó không hoạt động ... Bạn có ý tưởng không? Mã này cũng đang sử dụng rất nhiều bộ nhớ nhưng đó là một vấn đề khác. Toàn bộ tập lệnh có sẵn tại đây https://github.com/ThibaudDauce/habreaker

+0

Làm thế nào để bạn biết nó doesn không làm việc? – Gurkenglas

+0

nó chỉ chạy mãi mãi và ăn tất cả RAM của tôi và tất cả bộ vi xử lý của tôi –

Trả lời

5

Tôi chắc chắn bạn muốn sử dụng parBuffer thay vì evalBuffer.

Xem này SO câu trả lời cho một lời giải thích tốt:

How to choose between parList and parBuffer?

Dưới đây là một số mã demo:

import qualified Data.Map.Strict as M 
import Control.Parallel.Strategies 
import System.Environment 
import Debug.Trace 

fib 0 = 0 
fib 1 = 1 
fib n = fib (n-2) + fib (n-1) 

fib' n | trace "calling fib" False = undefined 
fib' n = fib n 

theList = cycle [30,31,32] 

firstN :: Int -> [Int] 
firstN n = take n $ filter even $ map fib' theList 

firstNpar :: Int -> Int -> [Int] 
firstNpar n k = take n $ filter even $ runEval $ parBuffer k rseq $ map fib' theList 

main = do 
    (argn : argk : _) <- getArgs 
    let n = read argn 
    case argk of 
    "" -> print $ firstN n 
    _ -> let k = read argk in 
      print $ firstNpar n k 

Ví dụ chạy:

prog 20 2 +RTS -N2   -- I only have two cores 
prog 20 ''     -- run single threaded 
+0

Cảm ơn, nó hoạt động (https://github.com/ThibaudDauce/habreaker) nhưng nó không nhanh hơn… :-(Và tôi không thấy tất cả các bộ vi xử lý của tôi làm việc … –

+0

Hãy thử sử dụng 'rdeepseq' thay vì' rseq'. 'Rseq' làm việc cho ví dụ của tôi vì kết quả của' fib' chỉ là số, nhưng bạn đang tính toán một cặp để đánh giá WHNF sẽ không tính toán băm. – ErikR

Các vấn đề liên quan