Skip to content

Instantly share code, notes, and snippets.

@kgadek
Last active August 29, 2015 13:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kgadek/9357070 to your computer and use it in GitHub Desktop.
Save kgadek/9357070 to your computer and use it in GitHub Desktop.
Comparing fast & slow factorials
[1 of 1] Compiling Main ( bench.hs, bench.o )
==================== Tidy Core ====================
Result size of Tidy Core = {terms: 85, types: 57, coercions: 30}
lvl_r2PK :: Type.Integer
lvl_r2PK = __integer 0
main11 :: Type.Integer
[GblId,
Unf=Unf{Src=<vanilla>, TopLvl=True, Arity=0, Value=True,
ConLike=True, WorkFree=True, Expandable=True,
Guidance=IF_ARGS [] 100 0}]
main11 = __integer 1
naive [Occ=LoopBreaker]
:: Type.Integer -> Type.Integer
naive =
\ (ds_d1qJ :: Type.Integer) ->
case Type.eqInteger ds_d1qJ lvl_r2PK of _ {
False ->
Type.timesInteger
ds_d1qJ
(naive (Type.minusInteger ds_d1qJ main11));
True -> main11
}
main_fact' [Occ=LoopBreaker]
:: Type.Integer
-> Type.Integer -> Type.Integer
main_fact' =
\ (r_a116 :: Type.Integer)
(ds_d1qM :: Type.Integer) ->
case Type.eqInteger ds_d1qM lvl_r2PK of _ {
False ->
main_fact'
(Type.timesInteger r_a116 ds_d1qM)
(Type.minusInteger ds_d1qM main11);
True -> r_a116
}
main12 :: [Char]
[GblId,
Unf=Unf{Src=<vanilla>, TopLvl=True, Arity=0, Value=False,
ConLike=False, WorkFree=False, Expandable=False,
Guidance=IF_ARGS [] 60 0}]
main12 = unpackCString# "fast fact"
main10 :: Type.Integer -> Type.Integer
[GblId,
Arity=1,
Unf=Unf{Src=<vanilla>, TopLvl=True, Arity=0, Value=True,
ConLike=True, WorkFree=True, Expandable=True,
Guidance=IF_ARGS [] 20 60}]
main10 = main_fact' main11
main6 :: Type.Integer
[GblId,
Unf=Unf{Src=<vanilla>, TopLvl=True, Arity=0, Value=True,
ConLike=True, WorkFree=True, Expandable=True,
Guidance=IF_ARGS [] 100 0}]
main6 = __integer 50000
main9 :: Criterion.Types.Pure
[GblId,
Unf=Unf{Src=<vanilla>, TopLvl=True, Arity=0, Value=True,
ConLike=True, WorkFree=False, Expandable=True,
Guidance=IF_ARGS [] 10 30}]
main9 =
Criterion.Types.WHNF
@ Type.Integer
@ Type.Integer
main10
main6
main8 :: Criterion.Types.Benchmark
[GblId,
Unf=Unf{Src=<vanilla>, TopLvl=True, Arity=0, Value=True,
ConLike=True, WorkFree=False, Expandable=True,
Guidance=IF_ARGS [] 10 40}]
main8 =
Criterion.Types.Benchmark
@ Criterion.Types.Pure
(Criterion.Types.$fBenchmarkablePure_$crun
`cast` (Sym
<(Criterion.Types.NTCo:Benchmarkable <Criterion.Types.Pure>)>
:: (Criterion.Types.Pure -> Int -> IO ())
~#
Criterion.Types.Benchmarkable Criterion.Types.Pure))
main12
main9
main7 :: [Char]
[GblId,
Unf=Unf{Src=<vanilla>, TopLvl=True, Arity=0, Value=False,
ConLike=False, WorkFree=False, Expandable=False,
Guidance=IF_ARGS [] 60 0}]
main7 = unpackCString# "naive fact"
main5 :: Criterion.Types.Pure
[GblId,
Unf=Unf{Src=<vanilla>, TopLvl=True, Arity=0, Value=True,
ConLike=True, WorkFree=False, Expandable=True,
Guidance=IF_ARGS [] 10 30}]
main5 =
Criterion.Types.WHNF
@ Type.Integer
@ Type.Integer
naive
main6
main4 :: Criterion.Types.Benchmark
[GblId,
Unf=Unf{Src=<vanilla>, TopLvl=True, Arity=0, Value=True,
ConLike=True, WorkFree=False, Expandable=True,
Guidance=IF_ARGS [] 10 40}]
main4 =
Criterion.Types.Benchmark
@ Criterion.Types.Pure
(Criterion.Types.$fBenchmarkablePure_$crun
`cast` (Sym
<(Criterion.Types.NTCo:Benchmarkable <Criterion.Types.Pure>)>
:: (Criterion.Types.Pure -> Int -> IO ())
~#
Criterion.Types.Benchmarkable Criterion.Types.Pure))
main7
main5
main3 :: [Criterion.Types.Benchmark]
[GblId,
Unf=Unf{Src=<vanilla>, TopLvl=True, Arity=0, Value=True,
ConLike=True, WorkFree=False, Expandable=True,
Guidance=IF_ARGS [] 10 30}]
main3 =
:
@ Criterion.Types.Benchmark
main4
([] @ Criterion.Types.Benchmark)
main2 :: [Criterion.Types.Benchmark]
[GblId,
Unf=Unf{Src=<vanilla>, TopLvl=True, Arity=0, Value=True,
ConLike=True, WorkFree=False, Expandable=True,
Guidance=IF_ARGS [] 10 30}]
main2 =
: @ Criterion.Types.Benchmark main8 main3
main1
:: State# RealWorld
-> (# State# RealWorld, () #)
[GblId,
Arity=1,
Unf=Unf{Src=<vanilla>, TopLvl=True, Arity=1, Value=True,
ConLike=True, WorkFree=True, Expandable=True,
Guidance=IF_ARGS [0] 50 0}]
main1 =
\ (eta_B1 :: State# RealWorld) ->
Criterion.defaultMain3
Criterion.Config.defaultConfig
(Criterion.defaultMain2
`cast` ((<Criterion.Config.Config>
-> Sym <(NTCo:IO <()>)>) ; (Sym
<(Control.Monad.Trans.Reader.NTCo:ReaderT
<Criterion.Config.Config>
<IO>
<()>)> ; Sym
<(Criterion.Monad.NTCo:Criterion)> <()>)
:: (Criterion.Config.Config
-> State# RealWorld
-> (# State# RealWorld, () #))
~#
Criterion.Monad.Criterion ()))
main2
eta_B1
main :: IO ()
[GblId,
Arity=1,
Unf=Unf{Src=<vanilla>, TopLvl=True, Arity=0, Value=True,
ConLike=True, WorkFree=True, Expandable=True,
Guidance=ALWAYS_IF(unsat_ok=True,boring_ok=True)}]
main =
main1
`cast` (Sym <(NTCo:IO <()>)>
:: (State# RealWorld
-> (# State# RealWorld, () #))
~#
IO ())
main13
:: State# RealWorld
-> (# State# RealWorld, () #)
[GblId,
Arity=1,
Unf=Unf{Src=<vanilla>, TopLvl=True, Arity=1, Value=True,
ConLike=True, WorkFree=True, Expandable=True,
Guidance=IF_ARGS [0] 30 0}]
main13 =
\ (eta_B1 :: State# RealWorld) ->
runMainIO1
@ ()
(main1
`cast` (Sym <(NTCo:IO <()>)>
:: (State# RealWorld
-> (# State# RealWorld, () #))
~#
IO ()))
eta_B1
:main :: IO ()
[GblId,
Arity=1,
Unf=Unf{Src=<vanilla>, TopLvl=True, Arity=0, Value=True,
ConLike=True, WorkFree=True, Expandable=True,
Guidance=ALWAYS_IF(unsat_ok=True,boring_ok=True)}]
:main =
main13
`cast` (Sym <(NTCo:IO <()>)>
:: (State# RealWorld
-> (# State# RealWorld, () #))
~#
IO ())
==================== Asm code ====================
.data
.align 3
.align 0
.globl __stginit_main:Main
__stginit_main:Main:
.globl __stginit_main::Main
__stginit_main::Main:
.data
.align 3
.align 0
lvl_r2PK_closure:
.quad Type.S#_static_info
.quad 0
.data
.align 3
.align 0
.globl main11_closure
main11_closure:
.quad Type.S#_static_info
.quad 1
.const_data
.align 3
.align 0
naive_srt:
.quad naive_closure
.quad main11_closure
.quad lvl_r2PK_closure
.data
.align 3
.align 0
.globl naive_closure
naive_closure:
.quad naive_info
.quad 0
.text
.align 3
s2Qb_info_dsp:
.quad 1
.quad 32
s2Qb_info:
_c2QJ:
movq 8(%rbp),%r14
movq %rbx,%rsi
addq $16,%rbp
jmp Type.timesInteger_info
.long s2Qb_info - s2Qb_info_dsp
.text
.align 3
s2PT_info_dsp:
.quad naive_srt-(s2PT_info)+0
.quad 1
.quad 4294967328
s2PT_info:
_c2QM:
movq %rbx,%r14
leaq s2Qb_info(%rip),%rax
movq %rax,0(%rbp)
jmp naive_info
.long s2PT_info - s2PT_info_dsp
.text
.align 3
s2Qc_info_dsp:
.quad naive_srt-(s2Qc_info)+0
.quad 1
.quad 12884901920
s2Qc_info:
_c2QS:
andq $7,%rbx
cmpq $2,%rbx
jae _c2QT
movq 8(%rbp),%r14
leaq main11_closure(%rip),%rax
leaq 1(%rax),%rsi
leaq s2PT_info(%rip),%rax
movq %rax,0(%rbp)
jmp Type.minusInteger_info
_c2QT:
leaq main11_closure(%rip),%rax
leaq 1(%rax),%rbx
addq $16,%rbp
jmp *0(%rbp)
.long s2Qc_info - s2Qc_info_dsp
.text
.align 3
naive_info_dsp:
.quad naive_srt-(naive_info)+0
.quad 4294967301
.quad 0
.quad 30064771087
.globl naive_info
naive_info:
_c2R2:
leaq -16(%rbp),%rax
cmpq %r15,%rax
jb _c2R4
movq %r14,-8(%rbp)
leaq lvl_r2PK_closure(%rip),%rax
leaq 1(%rax),%rsi
leaq s2Qc_info(%rip),%rax
movq %rax,-16(%rbp)
addq $-16,%rbp
jmp Type.eqInteger_info
_c2R4:
leaq naive_closure(%rip),%rbx
jmp *-8(%r13)
.long naive_info - naive_info_dsp
.const_data
.align 3
.align 0
main_fact'_srt:
.quad main11_closure
.quad main_fact'_closure
.quad lvl_r2PK_closure
.data
.align 3
.align 0
.globl main_fact'_closure
main_fact'_closure:
.quad main_fact'_info
.quad 0
.text
.align 3
s2Rb_info_dsp:
.quad main_fact'_srt-(s2Rb_info)+8
.quad 1
.quad 4294967328
s2Rb_info:
_c2RG:
movq %rbx,%r14
movq 8(%rbp),%rsi
addq $16,%rbp
jmp main_fact'_info
.long s2Rb_info - s2Rb_info_dsp
.text
.align 3
s2Ra_info_dsp:
.quad main_fact'_srt-(s2Ra_info)+8
.quad 2
.quad 4294967328
s2Ra_info:
_c2RJ:
movq 8(%rbp),%r14
movq 16(%rbp),%rsi
movq %rbx,16(%rbp)
leaq s2Rb_info(%rip),%rax
movq %rax,8(%rbp)
addq $8,%rbp
jmp Type.timesInteger_info
.long s2Ra_info - s2Ra_info_dsp
.text
.align 3
s2Rc_info_dsp:
.quad main_fact'_srt-(s2Rc_info)+0
.quad 2
.quad 12884901920
s2Rc_info:
_c2RP:
andq $7,%rbx
cmpq $2,%rbx
jae _c2RQ
movq 16(%rbp),%r14
leaq main11_closure(%rip),%rax
leaq 1(%rax),%rsi
leaq s2Ra_info(%rip),%rax
movq %rax,0(%rbp)
jmp Type.minusInteger_info
_c2RQ:
movq 8(%rbp),%rbx
addq $24,%rbp
andq $-8,%rbx
jmp *(%rbx)
.long s2Rc_info - s2Rc_info_dsp
.text
.align 3
main_fact'_info_dsp:
.quad main_fact'_srt-(main_fact'_info)+0
.quad 8589934604
.quad 0
.quad 30064771087
.globl main_fact'_info
main_fact'_info:
_c2RZ:
leaq -24(%rbp),%rax
cmpq %r15,%rax
jb _c2S1
movq %r14,-16(%rbp)
movq %rsi,-8(%rbp)
movq %rsi,%r14
leaq lvl_r2PK_closure(%rip),%rax
leaq 1(%rax),%rsi
leaq s2Rc_info(%rip),%rax
movq %rax,-24(%rbp)
addq $-24,%rbp
jmp Type.eqInteger_info
_c2S1:
leaq main_fact'_closure(%rip),%rbx
jmp *-8(%r13)
.long main_fact'_info - main_fact'_info_dsp
.data
.align 3
.align 0
.globl main12_closure
main12_closure:
.quad main12_info
.quad 0
.quad 0
.quad 0
.const
.align 3
.align 0
c2Sf_str:
.byte 102
.byte 97
.byte 115
.byte 116
.byte 32
.byte 102
.byte 97
.byte 99
.byte 116
.byte 0
.text
.align 3
main12_info_dsp:
.quad 0
.quad 22
.globl main12_info
main12_info:
_c2Sj:
leaq -16(%rbp),%rax
cmpq %r15,%rax
jb _c2Sl
addq $16,%r12
cmpq 144(%r13),%r12
ja _c2Sn
movq stg_CAF_BLACKHOLE_info@GOTPCREL(%rip),%rax
movq %rax,-8(%r12)
movq 160(%r13),%rax
movq %rax,0(%r12)
movq %r13,%rdi
movq %rbx,%rsi
leaq -8(%r12),%rdx
subq $8,%rsp
movl $0,%eax
call newCAF
addq $8,%rsp
testq %rax,%rax
je _c2So
_c2Sp:
movq stg_bh_upd_frame_info@GOTPCREL(%rip),%rax
movq %rax,-16(%rbp)
leaq -8(%r12),%rax
movq %rax,-8(%rbp)
leaq c2Sf_str(%rip),%r14
addq $-16,%rbp
jmp unpackCString#_info
_c2Sn:
movq $16,192(%r13)
_c2Sl:
jmp *-16(%r13)
_c2So:
jmp *(%rbx)
.long main12_info - main12_info_dsp
.const_data
.align 3
.align 0
main10_srt:
.quad main11_closure
.quad main_fact'_closure
.data
.align 3
.align 0
.globl main10_closure
main10_closure:
.quad main10_info
.quad 0
.text
.align 3
main10_info_dsp:
.quad main10_srt-(main10_info)+0
.quad 4294967301
.quad 0
.quad 12884901903
.globl main10_info
main10_info:
_c2SE:
movq %r14,%rsi
leaq main11_closure(%rip),%rax
leaq 1(%rax),%r14
jmp main_fact'_info
.long main10_info - main10_info_dsp
.data
.align 3
.align 0
.globl main6_closure
main6_closure:
.quad Type.S#_static_info
.quad 50000
.data
.align 3
.align 0
.globl main9_closure
main9_closure:
.quad Criterion.Types.WHNF_static_info
.quad main10_closure+1
.quad main6_closure+1
.quad 0
.data
.align 3
.align 0
.globl main8_closure
main8_closure:
.quad Criterion.Types.Benchmark_static_info
.quad Criterion.Types.$fBenchmarkablePure_$crun_closure+3
.quad main12_closure
.quad main9_closure+1
.quad 0
.data
.align 3
.align 0
.globl main7_closure
main7_closure:
.quad main7_info
.quad 0
.quad 0
.quad 0
.const
.align 3
.align 0
c2SZ_str:
.byte 110
.byte 97
.byte 105
.byte 118
.byte 101
.byte 32
.byte 102
.byte 97
.byte 99
.byte 116
.byte 0
.text
.align 3
main7_info_dsp:
.quad 0
.quad 22
.globl main7_info
main7_info:
_c2T3:
leaq -16(%rbp),%rax
cmpq %r15,%rax
jb _c2T5
addq $16,%r12
cmpq 144(%r13),%r12
ja _c2T7
movq stg_CAF_BLACKHOLE_info@GOTPCREL(%rip),%rax
movq %rax,-8(%r12)
movq 160(%r13),%rax
movq %rax,0(%r12)
movq %r13,%rdi
movq %rbx,%rsi
leaq -8(%r12),%rdx
subq $8,%rsp
movl $0,%eax
call newCAF
addq $8,%rsp
testq %rax,%rax
je _c2T8
_c2T9:
movq stg_bh_upd_frame_info@GOTPCREL(%rip),%rax
movq %rax,-16(%rbp)
leaq -8(%r12),%rax
movq %rax,-8(%rbp)
leaq c2SZ_str(%rip),%r14
addq $-16,%rbp
jmp unpackCString#_info
_c2T7:
movq $16,192(%r13)
_c2T5:
jmp *-16(%r13)
_c2T8:
jmp *(%rbx)
.long main7_info - main7_info_dsp
.data
.align 3
.align 0
.globl main5_closure
main5_closure:
.quad Criterion.Types.WHNF_static_info
.quad naive_closure+1
.quad main6_closure+1
.quad 0
.data
.align 3
.align 0
.globl main4_closure
main4_closure:
.quad Criterion.Types.Benchmark_static_info
.quad Criterion.Types.$fBenchmarkablePure_$crun_closure+3
.quad main7_closure
.quad main5_closure+1
.quad 0
.data
.align 3
.align 0
.globl main3_closure
main3_closure:
.quad :_static_info
.quad main4_closure+1
.quad []_closure+1
.quad 0
.data
.align 3
.align 0
.globl main2_closure
main2_closure:
.quad :_static_info
.quad main8_closure+1
.quad main3_closure+2
.quad 0
.const_data
.align 3
.align 0
main1_srt:
.quad main2_closure
.quad Criterion.Config.defaultConfig_closure
.quad Criterion.defaultMain3_closure
.data
.align 3
.align 0
.globl main1_closure
main1_closure:
.quad main1_info
.quad 0
.text
.align 3
main1_info_dsp:
.quad main1_srt-(main1_info)+0
.quad 4294967299
.quad 0
.quad 30064771087
.globl main1_info
main1_info:
_c2TA:
leaq Criterion.Config.defaultConfig_closure(%rip),%r14
leaq Criterion.defaultMain2_closure(%rip),%rax
leaq 2(%rax),%rsi
leaq main2_closure(%rip),%rax
leaq 2(%rax),%rdi
jmp Criterion.defaultMain3_info
.long main1_info - main1_info_dsp
.const_data
.align 3
.align 0
main_srt:
.quad main1_closure
.data
.align 3
.align 0
.globl main_closure
main_closure:
.quad main_info
.quad 0
.text
.align 3
main_info_dsp:
.quad main_srt-(main_info)+0
.quad 4294967299
.quad 0
.quad 4294967311
.globl main_info
main_info:
_c2TL:
jmp main1_info
.long main_info - main_info_dsp
.const_data
.align 3
.align 0
main13_srt:
.quad runMainIO1_closure
.quad main1_closure
.data
.align 3
.align 0
.globl main13_closure
main13_closure:
.quad main13_info
.quad 0
.text
.align 3
main13_info_dsp:
.quad main13_srt-(main13_info)+0
.quad 4294967299
.quad 0
.quad 12884901903
.globl main13_info
main13_info:
_c2TU:
leaq main1_closure(%rip),%rax
leaq 1(%rax),%r14
jmp runMainIO1_info
.long main13_info - main13_info_dsp
.const_data
.align 3
.align 0
:main_srt:
.quad main13_closure
.data
.align 3
.align 0
.globl :main_closure
:main_closure:
.quad :main_info
.quad 0
.text
.align 3
:main_info_dsp:
.quad :main_srt-(:main_info)+0
.quad 4294967299
.quad 0
.quad 4294967311
.globl :main_info
:main_info:
_c2U4:
jmp main13_info
.long :main_info - :main_info_dsp
Linking bench ...
import Criterion.Main
main :: IO ()
main = defaultMain [
bench "fast fact" $ whnf fact 10000
, bench "naive fact" $ whnf naive 10000
]
fact :: Integer -> Integer
fact = fact' 1
where fact' r 0 = r
fact' r n = fact' (r*n) (n-1)
naive :: Integer -> Integer
naive 0 = 1
naive x = x * naive (x - 1)
[1 of 1] Compiling Main ( fast.hs, fast.o )
==================== Tidy Core ====================
Result size of Tidy Core = {terms: 46, types: 34, coercions: 9}
lvl_r1Jp :: Type.Integer
lvl_r1Jp = __integer 0
main5 :: Type.Integer
[GblId,
Unf=Unf{Src=<vanilla>, TopLvl=True, Arity=0, Value=True,
ConLike=True, WorkFree=True, Expandable=True,
Guidance=IF_ARGS [] 100 0}]
main5 = __integer 1
main_fact' [Occ=LoopBreaker]
:: Type.Integer
-> Type.Integer -> Type.Integer
main_fact' =
\ (r_ahz :: Type.Integer)
(ds_dvf :: Type.Integer) ->
case Type.eqInteger ds_dvf lvl_r1Jp of _ {
False ->
main_fact'
(Type.timesInteger r_ahz ds_dvf)
(Type.minusInteger ds_dvf main5);
True -> r_ahz
}
main4 :: Type.Integer
[GblId,
Unf=Unf{Src=<vanilla>, TopLvl=True, Arity=0, Value=True,
ConLike=True, WorkFree=True, Expandable=True,
Guidance=IF_ARGS [] 100 0}]
main4 = __integer 50000
main3 :: Type.Integer
[GblId,
Unf=Unf{Src=<vanilla>, TopLvl=True, Arity=0, Value=False,
ConLike=False, WorkFree=False, Expandable=False,
Guidance=IF_ARGS [] 30 0}]
main3 = main_fact' main5 main4
main2 :: [Char]
[GblId,
Unf=Unf{Src=<vanilla>, TopLvl=True, Arity=0, Value=False,
ConLike=False, WorkFree=False, Expandable=False,
Guidance=IF_ARGS [] 40 0}]
main2 =
$w$cshowsPrec 0 main3 ([] @ Char)
main1
:: State# RealWorld
-> (# State# RealWorld, () #)
[GblId,
Arity=1,
Unf=Unf{Src=<vanilla>, TopLvl=True, Arity=1, Value=True,
ConLike=True, WorkFree=True, Expandable=True,
Guidance=IF_ARGS [0] 50 0}]
main1 =
\ (eta_aw3 :: State# RealWorld) ->
Handle.Text.hPutStr2
Handle.FD.stdout main2 True eta_aw3
main :: IO ()
[GblId,
Arity=1,
Unf=Unf{Src=<vanilla>, TopLvl=True, Arity=0, Value=True,
ConLike=True, WorkFree=True, Expandable=True,
Guidance=ALWAYS_IF(unsat_ok=True,boring_ok=True)}]
main =
main1
`cast` (Sym <(NTCo:IO <()>)>
:: (State# RealWorld
-> (# State# RealWorld, () #))
~#
IO ())
main6
:: State# RealWorld
-> (# State# RealWorld, () #)
[GblId,
Arity=1,
Unf=Unf{Src=<vanilla>, TopLvl=True, Arity=1, Value=True,
ConLike=True, WorkFree=True, Expandable=True,
Guidance=IF_ARGS [0] 30 0}]
main6 =
\ (eta_B1 :: State# RealWorld) ->
runMainIO1
@ ()
(main1
`cast` (Sym <(NTCo:IO <()>)>
:: (State# RealWorld
-> (# State# RealWorld, () #))
~#
IO ()))
eta_B1
:main :: IO ()
[GblId,
Arity=1,
Unf=Unf{Src=<vanilla>, TopLvl=True, Arity=0, Value=True,
ConLike=True, WorkFree=True, Expandable=True,
Guidance=ALWAYS_IF(unsat_ok=True,boring_ok=True)}]
:main =
main6
`cast` (Sym <(NTCo:IO <()>)>
:: (State# RealWorld
-> (# State# RealWorld, () #))
~#
IO ())
==================== Asm code ====================
.data
.align 3
.align 0
.globl __stginit_main:Main
__stginit_main:Main:
.globl __stginit_main::Main
__stginit_main::Main:
.data
.align 3
.align 0
lvl_r1Jp_closure:
.quad Type.S#_static_info
.quad 0
.data
.align 3
.align 0
.globl main5_closure
main5_closure:
.quad Type.S#_static_info
.quad 1
.const_data
.align 3
.align 0
main_fact'_srt:
.quad main5_closure
.quad main_fact'_closure
.quad lvl_r1Jp_closure
.data
.align 3
.align 0
.globl main_fact'_closure
main_fact'_closure:
.quad main_fact'_info
.quad 0
.text
.align 3
s1JL_info_dsp:
.quad main_fact'_srt-(s1JL_info)+8
.quad 1
.quad 4294967328
s1JL_info:
_c1Kj:
movq %rbx,%r14
movq 8(%rbp),%rsi
addq $16,%rbp
jmp main_fact'_info
.long s1JL_info - s1JL_info_dsp
.text
.align 3
s1JK_info_dsp:
.quad main_fact'_srt-(s1JK_info)+8
.quad 2
.quad 4294967328
s1JK_info:
_c1Km:
movq 8(%rbp),%r14
movq 16(%rbp),%rsi
movq %rbx,16(%rbp)
leaq s1JL_info(%rip),%rax
movq %rax,8(%rbp)
addq $8,%rbp
jmp Type.timesInteger_info
.long s1JK_info - s1JK_info_dsp
.text
.align 3
s1JM_info_dsp:
.quad main_fact'_srt-(s1JM_info)+0
.quad 2
.quad 12884901920
s1JM_info:
_c1Ks:
andq $7,%rbx
cmpq $2,%rbx
jae _c1Kt
movq 16(%rbp),%r14
leaq main5_closure(%rip),%rax
leaq 1(%rax),%rsi
leaq s1JK_info(%rip),%rax
movq %rax,0(%rbp)
jmp Type.minusInteger_info
_c1Kt:
movq 8(%rbp),%rbx
addq $24,%rbp
andq $-8,%rbx
jmp *(%rbx)
.long s1JM_info - s1JM_info_dsp
.text
.align 3
main_fact'_info_dsp:
.quad main_fact'_srt-(main_fact'_info)+0
.quad 8589934604
.quad 0
.quad 30064771087
.globl main_fact'_info
main_fact'_info:
_c1KC:
leaq -24(%rbp),%rax
cmpq %r15,%rax
jb _c1KE
movq %r14,-16(%rbp)
movq %rsi,-8(%rbp)
movq %rsi,%r14
leaq lvl_r1Jp_closure(%rip),%rax
leaq 1(%rax),%rsi
leaq s1JM_info(%rip),%rax
movq %rax,-24(%rbp)
addq $-24,%rbp
jmp Type.eqInteger_info
_c1KE:
leaq main_fact'_closure(%rip),%rbx
jmp *-8(%r13)
.long main_fact'_info - main_fact'_info_dsp
.data
.align 3
.align 0
.globl main4_closure
main4_closure:
.quad Type.S#_static_info
.quad 50000
.const_data
.align 3
.align 0
main3_srt:
.quad main4_closure
.quad main5_closure
.quad main_fact'_closure
.data
.align 3
.align 0
.globl main3_closure
main3_closure:
.quad main3_info
.quad 0
.quad 0
.quad 0
.text
.align 3
main3_info_dsp:
.quad main3_srt-(main3_info)+0
.quad 0
.quad 30064771094
.globl main3_info
main3_info:
_c1KX:
leaq -16(%rbp),%rax
cmpq %r15,%rax
jb _c1KZ
addq $16,%r12
cmpq 144(%r13),%r12
ja _c1L1
movq stg_CAF_BLACKHOLE_info@GOTPCREL(%rip),%rax
movq %rax,-8(%r12)
movq 160(%r13),%rax
movq %rax,0(%r12)
movq %r13,%rdi
movq %rbx,%rsi
leaq -8(%r12),%rdx
subq $8,%rsp
movl $0,%eax
call newCAF
addq $8,%rsp
testq %rax,%rax
je _c1L2
_c1L3:
movq stg_bh_upd_frame_info@GOTPCREL(%rip),%rax
movq %rax,-16(%rbp)
leaq -8(%r12),%rax
movq %rax,-8(%rbp)
leaq main5_closure(%rip),%rax
leaq 1(%rax),%r14
leaq main4_closure(%rip),%rax
leaq 1(%rax),%rsi
addq $-16,%rbp
jmp main_fact'_info
_c1L1:
movq $16,192(%r13)
_c1KZ:
jmp *-16(%r13)
_c1L2:
jmp *(%rbx)
.long main3_info - main3_info_dsp
.const_data
.align 3
.align 0
main2_srt:
.quad $w$cshowsPrec_closure
.quad main3_closure
.data
.align 3
.align 0
.globl main2_closure
main2_closure:
.quad main2_info
.quad 0
.quad 0
.quad 0
.text
.align 3
main2_info_dsp:
.quad main2_srt-(main2_info)+0
.quad 0
.quad 12884901910
.globl main2_info
main2_info:
_c1Lo:
leaq -16(%rbp),%rax
cmpq %r15,%rax
jb _c1Lq
addq $16,%r12
cmpq 144(%r13),%r12
ja _c1Ls
movq stg_CAF_BLACKHOLE_info@GOTPCREL(%rip),%rax
movq %rax,-8(%r12)
movq 160(%r13),%rax
movq %rax,0(%r12)
movq %r13,%rdi
movq %rbx,%rsi
leaq -8(%r12),%rdx
subq $8,%rsp
movl $0,%eax
call newCAF
addq $8,%rsp
testq %rax,%rax
je _c1Lt
_c1Lu:
movq stg_bh_upd_frame_info@GOTPCREL(%rip),%rax
movq %rax,-16(%rbp)
leaq -8(%r12),%rax
movq %rax,-8(%rbp)
xorl %r14d,%r14d
leaq main3_closure(%rip),%rsi
leaq []_closure(%rip),%rax
leaq 1(%rax),%rdi
addq $-16,%rbp
jmp $w$cshowsPrec_info
_c1Ls:
movq $16,192(%r13)
_c1Lq:
jmp *-16(%r13)
_c1Lt:
jmp *(%rbx)
.long main2_info - main2_info_dsp
.const_data
.align 3
.align 0
main1_srt:
.quad Handle.Text.hPutStr2_closure
.quad Handle.FD.stdout_closure
.quad main2_closure
.data
.align 3
.align 0
.globl main1_closure
main1_closure:
.quad main1_info
.quad 0
.text
.align 3
main1_info_dsp:
.quad main1_srt-(main1_info)+0
.quad 4294967299
.quad 0
.quad 30064771087
.globl main1_info
main1_info:
_c1LK:
leaq Handle.FD.stdout_closure(%rip),%r14
leaq main2_closure(%rip),%rsi
leaq True_closure(%rip),%rax
leaq 2(%rax),%rdi
jmp Handle.Text.hPutStr2_info
.long main1_info - main1_info_dsp
.const_data
.align 3
.align 0
main_srt:
.quad main1_closure
.data
.align 3
.align 0
.globl main_closure
main_closure:
.quad main_info
.quad 0
.text
.align 3
main_info_dsp:
.quad main_srt-(main_info)+0
.quad 4294967299
.quad 0
.quad 4294967311
.globl main_info
main_info:
_c1LU:
jmp main1_info
.long main_info - main_info_dsp
.const_data
.align 3
.align 0
main6_srt:
.quad runMainIO1_closure
.quad main1_closure
.data
.align 3
.align 0
.globl main6_closure
main6_closure:
.quad main6_info
.quad 0
.text
.align 3
main6_info_dsp:
.quad main6_srt-(main6_info)+0
.quad 4294967299
.quad 0
.quad 12884901903
.globl main6_info
main6_info:
_c1M3:
leaq main1_closure(%rip),%rax
leaq 1(%rax),%r14
jmp runMainIO1_info
.long main6_info - main6_info_dsp
.const_data
.align 3
.align 0
:main_srt:
.quad main6_closure
.data
.align 3
.align 0
.globl :main_closure
:main_closure:
.quad :main_info
.quad 0
.text
.align 3
:main_info_dsp:
.quad :main_srt-(:main_info)+0
.quad 4294967299
.quad 0
.quad 4294967311
.globl :main_info
:main_info:
_c1Md:
jmp main6_info
.long :main_info - :main_info_dsp
Linking fast ...
main :: IO ()
main = print $ fact 50000
fact :: Integer -> Integer
fact = fact' 1
where fact' r 0 = r
fact' r n = fact' (r*n) (n-1)
[1 of 1] Compiling Main ( naive.hs, naive.o )
==================== Tidy Core ====================
Result size of Tidy Core = {terms: 43, types: 32, coercions: 9}
lvl_r1Gr :: Type.Integer
lvl_r1Gr = __integer 0
lvl1_r1Gs :: Type.Integer
lvl1_r1Gs = __integer 1
naive [Occ=LoopBreaker]
:: Type.Integer -> Type.Integer
naive =
\ (ds_dsv :: Type.Integer) ->
case Type.eqInteger ds_dsv lvl_r1Gr of _ {
False ->
Type.timesInteger
ds_dsv
(naive (Type.minusInteger ds_dsv lvl1_r1Gs));
True -> lvl1_r1Gs
}
main4 :: Type.Integer
[GblId,
Unf=Unf{Src=<vanilla>, TopLvl=True, Arity=0, Value=True,
ConLike=True, WorkFree=True, Expandable=True,
Guidance=IF_ARGS [] 100 0}]
main4 = __integer 100000
main3 :: Type.Integer
[GblId,
Unf=Unf{Src=<vanilla>, TopLvl=True, Arity=0, Value=False,
ConLike=False, WorkFree=False, Expandable=False,
Guidance=IF_ARGS [] 20 0}]
main3 = naive main4
main2 :: [Char]
[GblId,
Unf=Unf{Src=<vanilla>, TopLvl=True, Arity=0, Value=False,
ConLike=False, WorkFree=False, Expandable=False,
Guidance=IF_ARGS [] 40 0}]
main2 =
$w$cshowsPrec 0 main3 ([] @ Char)
main1
:: State# RealWorld
-> (# State# RealWorld, () #)
[GblId,
Arity=1,
Unf=Unf{Src=<vanilla>, TopLvl=True, Arity=1, Value=True,
ConLike=True, WorkFree=True, Expandable=True,
Guidance=IF_ARGS [0] 50 0}]
main1 =
\ (eta_ata :: State# RealWorld) ->
Handle.Text.hPutStr2
Handle.FD.stdout main2 True eta_ata
main :: IO ()
[GblId,
Arity=1,
Unf=Unf{Src=<vanilla>, TopLvl=True, Arity=0, Value=True,
ConLike=True, WorkFree=True, Expandable=True,
Guidance=ALWAYS_IF(unsat_ok=True,boring_ok=True)}]
main =
main1
`cast` (Sym <(NTCo:IO <()>)>
:: (State# RealWorld
-> (# State# RealWorld, () #))
~#
IO ())
main5
:: State# RealWorld
-> (# State# RealWorld, () #)
[GblId,
Arity=1,
Unf=Unf{Src=<vanilla>, TopLvl=True, Arity=1, Value=True,
ConLike=True, WorkFree=True, Expandable=True,
Guidance=IF_ARGS [0] 30 0}]
main5 =
\ (eta_B1 :: State# RealWorld) ->
runMainIO1
@ ()
(main1
`cast` (Sym <(NTCo:IO <()>)>
:: (State# RealWorld
-> (# State# RealWorld, () #))
~#
IO ()))
eta_B1
:main :: IO ()
[GblId,
Arity=1,
Unf=Unf{Src=<vanilla>, TopLvl=True, Arity=0, Value=True,
ConLike=True, WorkFree=True, Expandable=True,
Guidance=ALWAYS_IF(unsat_ok=True,boring_ok=True)}]
:main =
main5
`cast` (Sym <(NTCo:IO <()>)>
:: (State# RealWorld
-> (# State# RealWorld, () #))
~#
IO ())
==================== Asm code ====================
.data
.align 3
.align 0
.globl __stginit_main:Main
__stginit_main:Main:
.globl __stginit_main::Main
__stginit_main::Main:
.data
.align 3
.align 0
lvl_r1Gr_closure:
.quad Type.S#_static_info
.quad 0
.data
.align 3
.align 0
lvl1_r1Gs_closure:
.quad Type.S#_static_info
.quad 1
.const_data
.align 3
.align 0
naive_srt:
.quad naive_closure
.quad lvl_r1Gr_closure
.quad lvl1_r1Gs_closure
.data
.align 3
.align 0
.globl naive_closure
naive_closure:
.quad naive_info
.quad 0
.text
.align 3
s1GM_info_dsp:
.quad 1
.quad 32
s1GM_info:
_c1Hk:
movq 8(%rbp),%r14
movq %rbx,%rsi
addq $16,%rbp
jmp Type.timesInteger_info
.long s1GM_info - s1GM_info_dsp
.text
.align 3
s1GB_info_dsp:
.quad naive_srt-(s1GB_info)+0
.quad 1
.quad 4294967328
s1GB_info:
_c1Hn:
movq %rbx,%r14
leaq s1GM_info(%rip),%rax
movq %rax,0(%rbp)
jmp naive_info
.long s1GB_info - s1GB_info_dsp
.text
.align 3
s1GN_info_dsp:
.quad naive_srt-(s1GN_info)+0
.quad 1
.quad 21474836512
s1GN_info:
_c1Ht:
andq $7,%rbx
cmpq $2,%rbx
jae _c1Hu
movq 8(%rbp),%r14
leaq lvl1_r1Gs_closure(%rip),%rax
leaq 1(%rax),%rsi
leaq s1GB_info(%rip),%rax
movq %rax,0(%rbp)
jmp Type.minusInteger_info
_c1Hu:
leaq lvl1_r1Gs_closure(%rip),%rax
leaq 1(%rax),%rbx
addq $16,%rbp
jmp *0(%rbp)
.long s1GN_info - s1GN_info_dsp
.text
.align 3
naive_info_dsp:
.quad naive_srt-(naive_info)+0
.quad 4294967301
.quad 0
.quad 30064771087
.globl naive_info
naive_info:
_c1HD:
leaq -16(%rbp),%rax
cmpq %r15,%rax
jb _c1HF
movq %r14,-8(%rbp)
leaq lvl_r1Gr_closure(%rip),%rax
leaq 1(%rax),%rsi
leaq s1GN_info(%rip),%rax
movq %rax,-16(%rbp)
addq $-16,%rbp
jmp Type.eqInteger_info
_c1HF:
leaq naive_closure(%rip),%rbx
jmp *-8(%r13)
.long naive_info - naive_info_dsp
.data
.align 3
.align 0
.globl main4_closure
main4_closure:
.quad Type.S#_static_info
.quad 100000
.const_data
.align 3
.align 0
main3_srt:
.quad naive_closure
.quad main4_closure
.data
.align 3
.align 0
.globl main3_closure
main3_closure:
.quad main3_info
.quad 0
.quad 0
.quad 0
.text
.align 3
main3_info_dsp:
.quad main3_srt-(main3_info)+0
.quad 0
.quad 12884901910
.globl main3_info
main3_info:
_c1HY:
leaq -16(%rbp),%rax
cmpq %r15,%rax
jb _c1I0
addq $16,%r12
cmpq 144(%r13),%r12
ja _c1I2
movq stg_CAF_BLACKHOLE_info@GOTPCREL(%rip),%rax
movq %rax,-8(%r12)
movq 160(%r13),%rax
movq %rax,0(%r12)
movq %r13,%rdi
movq %rbx,%rsi
leaq -8(%r12),%rdx
subq $8,%rsp
movl $0,%eax
call newCAF
addq $8,%rsp
testq %rax,%rax
je _c1I3
_c1I4:
movq stg_bh_upd_frame_info@GOTPCREL(%rip),%rax
movq %rax,-16(%rbp)
leaq -8(%r12),%rax
movq %rax,-8(%rbp)
leaq main4_closure(%rip),%rax
leaq 1(%rax),%r14
addq $-16,%rbp
jmp naive_info
_c1I2:
movq $16,192(%r13)
_c1I0:
jmp *-16(%r13)
_c1I3:
jmp *(%rbx)
.long main3_info - main3_info_dsp
.const_data
.align 3
.align 0
main2_srt:
.quad $w$cshowsPrec_closure
.quad main3_closure
.data
.align 3
.align 0
.globl main2_closure
main2_closure:
.quad main2_info
.quad 0
.quad 0
.quad 0
.text
.align 3
main2_info_dsp:
.quad main2_srt-(main2_info)+0
.quad 0
.quad 12884901910
.globl main2_info
main2_info:
_c1Io:
leaq -16(%rbp),%rax
cmpq %r15,%rax
jb _c1Iq
addq $16,%r12
cmpq 144(%r13),%r12
ja _c1Is
movq stg_CAF_BLACKHOLE_info@GOTPCREL(%rip),%rax
movq %rax,-8(%r12)
movq 160(%r13),%rax
movq %rax,0(%r12)
movq %r13,%rdi
movq %rbx,%rsi
leaq -8(%r12),%rdx
subq $8,%rsp
movl $0,%eax
call newCAF
addq $8,%rsp
testq %rax,%rax
je _c1It
_c1Iu:
movq stg_bh_upd_frame_info@GOTPCREL(%rip),%rax
movq %rax,-16(%rbp)
leaq -8(%r12),%rax
movq %rax,-8(%rbp)
xorl %r14d,%r14d
leaq main3_closure(%rip),%rsi
leaq []_closure(%rip),%rax
leaq 1(%rax),%rdi
addq $-16,%rbp
jmp $w$cshowsPrec_info
_c1Is:
movq $16,192(%r13)
_c1Iq:
jmp *-16(%r13)
_c1It:
jmp *(%rbx)
.long main2_info - main2_info_dsp
.const_data
.align 3
.align 0
main1_srt:
.quad Handle.Text.hPutStr2_closure
.quad Handle.FD.stdout_closure
.quad main2_closure
.data
.align 3
.align 0
.globl main1_closure
main1_closure:
.quad main1_info
.quad 0
.text
.align 3
main1_info_dsp:
.quad main1_srt-(main1_info)+0
.quad 4294967299
.quad 0
.quad 30064771087
.globl main1_info
main1_info:
_c1IK:
leaq Handle.FD.stdout_closure(%rip),%r14
leaq main2_closure(%rip),%rsi
leaq True_closure(%rip),%rax
leaq 2(%rax),%rdi
jmp Handle.Text.hPutStr2_info
.long main1_info - main1_info_dsp
.const_data
.align 3
.align 0
main_srt:
.quad main1_closure
.data
.align 3
.align 0
.globl main_closure
main_closure:
.quad main_info
.quad 0
.text
.align 3
main_info_dsp:
.quad main_srt-(main_info)+0
.quad 4294967299
.quad 0
.quad 4294967311
.globl main_info
main_info:
_c1IU:
jmp main1_info
.long main_info - main_info_dsp
.const_data
.align 3
.align 0
main5_srt:
.quad runMainIO1_closure
.quad main1_closure
.data
.align 3
.align 0
.globl main5_closure
main5_closure:
.quad main5_info
.quad 0
.text
.align 3
main5_info_dsp:
.quad main5_srt-(main5_info)+0
.quad 4294967299
.quad 0
.quad 12884901903
.globl main5_info
main5_info:
_c1J3:
leaq main1_closure(%rip),%rax
leaq 1(%rax),%r14
jmp runMainIO1_info
.long main5_info - main5_info_dsp
.const_data
.align 3
.align 0
:main_srt:
.quad main5_closure
.data
.align 3
.align 0
.globl :main_closure
:main_closure:
.quad :main_info
.quad 0
.text
.align 3
:main_info_dsp:
.quad :main_srt-(:main_info)+0
.quad 4294967299
.quad 0
.quad 4294967311
.globl :main_info
:main_info:
_c1Jd:
jmp main5_info
.long :main_info - :main_info_dsp
Linking naive ...
main :: IO ()
main = print $ naive 100000
naive :: Integer -> Integer
naive 0 = 1
naive x = x * naive (x - 1)
❯ ghc -O --make bench.hs
[1 of 1] Compiling Main ( bench.hs, bench.o )
Linking bench ...
❯ ./bench
warming up
estimating clock resolution...
mean is 1.177271 us (640001 iterations)
found 90407 outliers among 639999 samples (14.1%)
20 (3.1e-3%) low severe
90387 (14.1%) high severe
estimating cost of a clock call...
mean is 54.91035 ns (7 iterations)
benchmarking fast fact
collecting 100 samples, 1 iterations each, in estimated 28.93920 s
mean: 284.2608 ms, lb 281.3461 ms, ub 286.9861 ms, ci 0.950
std dev: 14.46975 ms, lb 13.17617 ms, ub 15.87717 ms, ci 0.950
variance introduced by outliers: 49.432%
variance is moderately inflated by outliers
benchmarking naive fact
collecting 100 samples, 1 iterations each, in estimated 31.89321 s
mean: 314.6559 ms, lb 312.0555 ms, ub 317.2963 ms, ci 0.950
std dev: 13.45321 ms, lb 12.06272 ms, ub 15.21999 ms, ci 0.950
variance introduced by outliers: 40.492%
variance is moderately inflated by outliers
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment