Optimization 为什么这个Haskell函数很慢?
我有一个单行函数,它占用了我25%的执行时间,这与我的直觉是背道而驰的 背景是一个用于棋盘游戏(Blokus)的AI,具体来说,我们在这里所做的是试图确定在特定棋盘格附近以特定方向放置一块棋子是否合法。我们已经预先计算了Word64(placementBitmap),它显示了工件在特定方向上占用的单元格,最近我们计算了Word64(cornerBitmap),它显示了该正方形周围可用的单元格。现在我们比较一下:Optimization 为什么这个Haskell函数很慢?,optimization,haskell,Optimization,Haskell,我有一个单行函数,它占用了我25%的执行时间,这与我的直觉是背道而驰的 背景是一个用于棋盘游戏(Blokus)的AI,具体来说,我们在这里所做的是试图确定在特定棋盘格附近以特定方向放置一块棋子是否合法。我们已经预先计算了Word64(placementBitmap),它显示了工件在特定方向上占用的单元格,最近我们计算了Word64(cornerBitmap),它显示了该正方形周围可用的单元格。现在我们比较一下: legalAt (TerritoryCorner _ _ cornerBitmap)
legalAt (TerritoryCorner _ _ cornerBitmap) (Placement _ _ _ placementBitmap) = (placementBitmap .&. cornerBitmap) == placementBitmap
我不明白这里的两个按位操作怎么会比计算cornerBitmap的过程占用更多的时间。拳击问题?我是哈斯克尔的新手
TerritoryCorner和Placement的数据构造函数的定义使得最后一个参数无论值多少都是严格的
所使用的上下文是列表理解:
[getMyChild corner placement | corner <- myCorners, placement <- myPlacements, legalAt corner placement]
您在32位平台上,因此64位操作是C调用,这使得它们比64位平台上的稍慢。然而,这不应该花那么多钱,而
legalAt
的核心就如人们所希望的那样好。我认为与您的想法相反,cornerBitmap
和placementBitmap
的计算以前从未进行过,并且是由legalAt
强制进行的,而分析器将成本归因于此
我们需要查看更多代码和上下文以了解更多信息。您是否在32位平台上?(最明显的是:使用
-O2
?)编译@ehird是的,(s)他在32位平台上,并进行了优化编译,尽管这可能是-O1
:)@DanielFischer:这将教会我把猜测作为注释而不是答案发表!)@爱尔德:别猜了,多读点核心,你就知道了;)我想我一定是误解了函数的调用方式,是的。这可能是因为它被称为比我最初认为的更经常地与其他事物相关。我想这个函数可能有点问题,这对于Haskell知识更丰富的人来说是显而易见的,但我想不是。我再看一眼,稍后再回来
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
}
}
}