Faster break and span for Prelude
Bas van Dijk
v.dijk.bas at gmail.com
Tue Dec 27 22:57:43 CET 2011
On 27 December 2011 22:40, Bas van Dijk <v.dijk.bas at gmail.com> wrote:
> However I do expect them to be significantly faster when they are
> applied fully saturated.
This looks to be correct when looking at the core of a fully saturated
application:
spanApplied = span (==1) (replicate 1000 1 :: [Int])
You can see that in the generated core the (==1) is passed to the
worker function $wspan:
spanApplied =
case $wspan@ Int (==1) (replicate 1000 1) of _
{ (# ww1_aoo, ww2_aop #)
$wspan =
\ (@ a_aa0)
(w_snj :: a_aa0 -> Bool)
(w1_snk :: [a_aa0]) ->
case w1_snk of wild_X9 {
[] -> (# [] @ a_aa0, [] @ a_aa0 #);
: x1_aas xs'_aat ->
case w_snj x1_aas of _ {
False -> (# [] @ a_aa0, wild_X9 #);
True ->
let {
ds_smn [Dmd=Just D(SS)] :: ([a_aa0], [a_aa0])
ds_smn =
case $wspan @ a_aa0 w_snj xs'_aat
of _ { (# ww1_snO, ww2_snP #) ->
(ww1_snO, ww2_snP)
} } in
(# :
@ a_aa0 x1_aas
(case ds_smn of _
{ (ys_Xdu, zs_Xdl) -> ys_Xdu })
,
case ds_smn of _
{ (ys_ad7, zs_Xdu) -> zs_Xdu }
#)
}
}
While in:
newSpanApplied = newspan (==1) (replicate 1000 1 :: [Int])
the (==1) is "fused" into the worker function $wgo:
newSpanApplied =
case $wgo (replicate 1000 1)
of _ { (# ww1_spk, ww2_spl #) -> (ww1_spk, ww2_spl)}
$wgo =
\ (w_soQ :: [Int]) ->
case w_soQ of wild_Xb {
[] ->
(# [] @ Int, [] @ Int #);
: x1_abE xs'_abF ->
case x1_abE of wild1_amK { I# x2_amM ->
case x2_amM of _ {
__DEFAULT -> (# [] @ Int, wild_Xb #);
1 ->
let {
ds_snn [Dmd=Just D(SS)] :: ([Int], [Int])
ds_snn =
case $wgo xs'_abF of _
{ (# ww1_spk, ww2_spl #) ->
(ww1_spk, ww2_spl)
}
} in
(# : @ Int
wild1_amK
( case ds_snn of _
{ (ys_Xmv, zs_Xmm) -> ys_Xmv })
, case ds_snn of _
{ (ys_am6, zs_Xmv) -> zs_Xmv }
#)
}
}
}
(BTW I'm using GHC-7.4.1-rc1)
Bas
More information about the Libraries
mailing list