I have a single line function that takes 25% of my runtime, which is very inconsistent for me.
Context is an AI for a board game (Blokus), and exactly what we are doing here is trying to determine whether it is legal to place a piece in a specific orientation in the vicinity of a specific board cell. We have previously calculated Word64 (placementBitmap), which shows which cells are occupied by a piece in a certain orientation, and recently, we have calculated Word64 (placementBitmap), which shows which cells are available around this square. So now we compare them:
legalAt (TerritoryCorner _ _ cornerBitmap) (Placement _ _ _ placementBitmap) = (placementBitmap .&. cornerBitmap) == placementBitmap
I donβt understand how a couple of bitwise operations here may take longer than the process of calculating cornerBitmap in the first place. Boxing questions? I am new to Haskell.
The data constructors for TerritoryCorner and Placement are defined so that the last argument is strict, for what it costs.
The context in which this is used is a list comprehension:
[getMyChild corner placement | corner <- myCorners, placement <- myPlacements, legalAt corner placement]
I managed to create the following Core, but I donβt know how to interpret it:
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