为什么这个Haskell函数变慢了?

时间:2012-01-05 14:27:49

标签: optimization haskell

我有一个单行函数占用了我执行时间的25%,这种方式对我来说非常违反直觉。

上下文是一个棋盘游戏的人工智能(Blokus),具体而言我们在这里做的是试图确定在特定棋盘区附近放置一个特定方向的棋子是否合法。我们已经预先计算了一个Word64(placementBitmap),它显示了特定方向的片段占用了哪些单元格,最近我们计算了一个Word64(cornerBitmap),它显示了这个方块周围可用的单元格。所以现在我们比较它们:

legalAt (TerritoryCorner _ _ cornerBitmap) (Placement _ _ _ placementBitmap) = (placementBitmap .&. cornerBitmap) == placementBitmap

我不明白这里的几个按位操作如何占用比首先计算cornerBitmap的过程更多的时间。拳击问题?我对Haskell很新。

定义了TerritoryCorner和Placement的数据构造函数,以便最后一个参数是严格的,无论价值多少。

使用它的上下文是列表理解:

[getMyChild corner placement | corner <- myCorners, placement <- myPlacements, legalAt corner placement]

我设法生成了以下Core,但我不知道如何解释它:

GameState.legalAt [InlPrag=INLINE[0]]
  :: Types.TerritoryCorner -> Types.Placement -> GHC.Bool.Bool
[GblId,
 Arity=2,
 Caf=NoCafRefs,
 Str=DmdType U(AAAL)U(UUUL),
 Unf=Unf{Src=InlineStable, TopLvl=True, Arity=2, Value=True,
         ConLike=True, Cheap=True, Expandable=True,
         Guidance=ALWAYS_IF(unsat_ok=True,boring_ok=False)
         Tmpl= \ (w_soat [Occ=Once!] :: Types.TerritoryCorner)
                 (w1_soaA [Occ=Once!] :: Types.Placement) ->
                 case w_soat of _ { Types.TerritoryCorner _ _ _ ww3_soay ->
                 case w1_soaA of _ { Types.Placement _ _ _ ww7_soaF ->
                 __scc {legalAt main:GameState}
                 case {__pkg_ccall ghc-prim hs_and64 GHC.Prim.Word64#
                               -> GHC.Prim.Word64#
                               -> GHC.Prim.State# GHC.Prim.RealWorld
                               -> (# GHC.Prim.State# GHC.Prim.RealWorld, GHC.Prim.Word64# #)}_aHK
                        ww7_soaF ww3_soay GHC.Prim.realWorld#
                 of _ { (# _, ds3_aHQ [Occ=Once] #) ->
                 GHC.IntWord64.eqWord64# ds3_aHQ ww7_soaF
                 }
                 }
                 }}]
GameState.legalAt =
  \ (w_soat :: Types.TerritoryCorner) (w1_soaA :: Types.Placement) ->
    case w_soat
    of _ { Types.TerritoryCorner ww_soav ww1_soaw ww2_soax ww3_soay ->
    case w1_soaA
    of _ { Types.Placement ww4_soaC ww5_soaD ww6_soaE ww7_soaF ->
    __scc {legalAt main:GameState}
    case {__pkg_ccall ghc-prim hs_and64 GHC.Prim.Word64#
                               -> GHC.Prim.Word64#
                               -> GHC.Prim.State# GHC.Prim.RealWorld
                               -> (# GHC.Prim.State# GHC.Prim.RealWorld, GHC.Prim.Word64# #)}_aHK
           ww7_soaF ww3_soay GHC.Prim.realWorld#
    of _ { (# _, ds3_aHQ #) ->
    GHC.IntWord64.eqWord64# ds3_aHQ ww7_soaF
    }
    }
    }

1 个答案:

答案 0 :(得分:4)

您使用的是32位平台,因此64位操作是C调用,这使得它们比64位平台慢一些。但是,这不应该花费太多,legalAt的核心就像人们所希望的那样好。我认为与您的信念相反,cornerBitmapplacementBitmap的计算以前没有完成,并且由legalAt强制执行,并且由分析器将成本归因于此。

我们需要查看更多代码和上下文以了解更多信息。