簡體   English   中英

Haskell中的復雜嵌套if else語句(性能)

[英]Complex nested if else statements in Haskell (Performance)

如果我想處理數億個數字並將它們通過if-else嵌套傳遞,例如(在過程中):

if( n > 0 ){
    if( n > 100 ) {
        if( n > 1000 ) {
           return 1
        }else{
           return 2
        }
    }else{
        if( n > 50 ) {
           return 3
        }else{
           return 4
        }          
}else{
    //more nested else cases
}

從程序上講,要獲得這些回報中的任何一個,都需要進行3次比較,以確保如果范圍設置正確(如果我現在放隨機數,不要介意),則平均情況是最佳的。 但是不確定在Haskell這樣的功能語言上,什么能帶來最佳性能(可讀性或鍵入的簡便性並不重要)。

例如,我可能可以直接編寫if else嵌套,或者對整個if路徑使用防護,例如:

| n > 1000 = 1
| n > 100 = 2
| n > 50 = 3
| n > 0 = 4
| etc

但是我想想,當n> 1000時,只有一個比較,對於0上的任何東西,等等,它的成本都將超過3。

這樣的結構可能會四次計算n> 0而不是分支:

| n > 0, n > 100, n > 1000 = 1
| n > 0, n > 100 = 2
| n > 0, n > 50 = 3
| n > 0 = 4
| etc

我也可以只使用一個函數,但是不確定函數是否便宜,因為比較起來會便宜一些。

好吧,雖然if語句並不特別Haskellers喜歡,沒有什么與他們了。 也許最好的事情就是

if n > 0
 then if n > 100
       then if n > 1000 then 1 else 2
       else if n > 50 then 3 else 4
 else ...

也就是說,最好將整個比較工作從庫中委派為合適的數據類型。 實際上,這些嵌套的比較看起來很像您要對Map進行硬編碼。

我可能會使用MaplookupLT操作或類似的方法來實現此目的。 例如:

import Data.Map.Strict as M
-- use a lambda to avoid recomputing results on each call
count = \n -> snd <$> M.lookupLT n results where
    results = M.fromAscList [(0,4),(50,3),(100,2),(1000,1)]

在ghci中:

> count 1
Just 4
> count 1001
Just 1
> count (-300)
Nothing

如果您的鍵碰巧是Int ,則可以通過在IntMap進行交換來使其速度更快。

這應該使您獲得的結果與最佳比較數非常接近-在IntMap情況下,甚至可能比嵌套的ifs還要少。 我不知道這種方法不一定是最快的方法,但是它是相當“識字的”:這段代碼的讀者將不必解密深層的ifs鏈來發現它的作用,然后在以后修改可能的結果(如果需要的話)將非常簡單。

您可以定義適當的決策樹:

data Tree n rv = Leaf rv | Node n (Tree n rv) (Tree n rv)

您的示例將被編碼為

 (Node 0 ({- else nodes -}) -- depending on your other cases
         (Node 100 (Node 50 (Leaf 4) (Leaf 3))
                   (Node 1000 (Leaf 2) (Leaf 1)))

(左和右子樹與<>=對應。如果要進一步區分>==可能需要進行一些調整。)

遍歷樹,您將n值與每個節點中的第一個值進行比較,返回第二個值或遞歸遍歷相應的子樹。

search :: (Eq a, Ord a) => a -> Tree a b ->b
search _ (Leaf x) = x
search x (Node y left right)| x < y = search x left
                                | otherwise = search x right

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM