- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想搜索一个列表,测试属性 X 的每个元素,然后在找到具有属性 X 的元素时返回。
这个列表非常大,可以从并行性中受益,但相对于计算时间而言, Spark 的成本相当高。 parListChunk
会很棒,但是它必须搜索整个列表。
有什么方法可以写出 parListChunk
之类的东西吗?但提前中止?
这是天真的搜索代码:
hasPropertyX :: Object -> Bool
anyObjectHasPropertyX :: [Object] -> Bool
anyObjectHasPropertyX [] = False
anyObjectHasPropertyX l
| hasPropertyX (head l) == True = True
| otherwise = anyObjectHasPropertyX (tail l)
anyObjectHasPropertyXPar [] = False
anyObjectHasPropertyXPar [a] = hasPropertyX a
anyObjectHasPropertyXPar (a:b:rest) = runEval $ do c1 <- rpar (force (hasPropertyX a))
c2 <- rpar (force (hasPropertyX b))
rseq c1
rseq c2
if (c1 == True) || (c2 == True) then return True else return (anyObjectHasPropertyXPar rest)
-N1
,很奇怪),但速度并不快(它通过扩展并行计算的数量有所帮助)。我相信它并没有太大的好处,因为它必须为列表中的每个元素触发一个线程。
parListChunk
的方法那只会触发n个线程并允许提前中止?
rseq
的并且有类似的东西
if (c1 == True) || (c2 == True) then ...
最佳答案
我认为您使用 Control.Parallel.Strategies
不会有太大的运气。 .该模块的一个关键特性是它表达了“确定性并行性”,因此程序的结果不受并行评估的影响。您描述的问题基本上是不确定的,因为线程正在竞相寻找第一个匹配项。
更新:我现在看到你只返回 True
如果找到该元素,则所需的行为在技术上是确定的。所以,也许有办法欺骗 Strategies
模块投入工作。不过,下面的实现似乎满足要求。
这是一个并行查找的实现 parFind
使用 Control.Concurrent
在 IO monad 中运行原语,似乎做你想做的事。两个MVars
使用:runningV
记录有多少线程仍在运行,以允许最后一个线程检测搜索失败;和 resultV
用于返回 Just
结果或Nothing
当最后一个线程检测到搜索失败时。请注意,与这个玩具示例不同,除非测试(您的 hasPropertyX
以上)比列表遍历工作量大得多,否则它的性能不太可能比单线程实现更好。
import Control.Monad
import Control.Concurrent
import Data.List
import System.Environment
-- Thin a list to every `n`th element starting with index `i`
thin :: Int -> Int -> [a] -> [a]
thin i n = unfoldr step . drop i
where step [] = Nothing
step (y:ys) = Just (y, drop (n-1) ys)
-- Use `n` parallel threads to find first element of `xs` satisfying `f`
parFind :: Int -> (a -> Bool) -> [a] -> IO (Maybe a)
parFind n f xs = do
resultV <- newEmptyMVar
runningV <- newMVar n
comparisonsV <- newMVar 0
threads <- forM [0..n-1] $ \i -> forkIO $ do
case find f (thin i n xs) of
Just x -> void (tryPutMVar resultV (Just x))
Nothing -> do m <- takeMVar runningV
if m == 1
then void (tryPutMVar resultV Nothing)
else putMVar runningV (m-1)
result <- readMVar resultV
mapM_ killThread threads
return result
myList :: [Int]
myList = [1..1000000000]
-- Use `n` threads to find first element equal to `y` in `myList`
run :: Int -> Int -> IO ()
run n y = do x <- parFind n (== y) myList
print x
-- e.g., stack ghc -- -O2 -threaded SearchList.hs
-- time ./SearchList +RTS -N4 -RTS 4 12345 # find 12345 using 4 threads -> 0.018s
-- time ./SearchList +RTS -N4 -RTS 4 -1 # full search w/o match -> 6.7s
main :: IO ()
main = do [n,y] <- getArgs
run (read n) (read y)
关于具有早期中止的 Haskell 并行搜索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44615468/
我有一个 javascript 函数,可以执行以下操作; 它将日期编辑框设置为与另一个日期编辑相同的日期。但是我希望它将 txt_Testin
我有一个输入框,类型为“时间”。我想将迟到时间 (23:00pm) 作为最小值,将早期时间 (6:00am) 作为最大值 - 创建一个 23pm - 6am 的范围。 (即中午 11 点、中午 12
使用 Joda 时间并获得类似以下行为的最简单方法是什么: public boolean check( DateTime checkTime ) { DateTime someTime = n
我想计算 updated_at 比 created_at 早 2 小时的记录。 代码 $teLang = $kentekens->where('updated_at', '>', 'created_a
我是一名优秀的程序员,十分优秀!