Re: [Haskell-beginners] Function definition order and performance

I have not met a performance issue yet. Thanks. I'm just a beginner. I was just wondering how they will be different. For instance,
safeHead [] = Nothing safeHead (x : xs) = Just x
vesus
safeHead (x : xs) = Just x safeHead [] = Nothing
There is no difference in this case. GHC compiles that down to the very same thing. Given this file:
safeHead [] = Nothing safeHead (x:xs) = Just x
safeHead' (x:xs) = Just x safeHead' [] = Nothing
You can look at the ghc core (the intermediate compiler output produced by GHC) to find out what the difference is. Core is basically like machine-generated Haskell with some syntactical oddities. Don Steward's ghc-core program on hackage displays core nicely. Here are the relevant core blocks:
safeHead' = \ (@ a_acw) (ds_dcU :: [a_acw]) -> case ds_dcU of _ { [] -> Data.Maybe.Nothing @ a_acw; : x_abJ xs_abK -> Data.Maybe.Just @ a_acw x_abJ }
safeHead = \ (@ a_acy) (ds_dcX :: [a_acy]) -> case ds_dcX of _ { [] -> Data.Maybe.Nothing @ a_acy; : x_abx xs_aby -> Data.Maybe.Just @ a_acy x_abx }
And, well, they're exactly the same (sans a few differences in variable naming, which have no impact whatsoever.) Your pattern match gets compiled down to a case pattern match, and the arguments are re-ordered. While you *can* look at the assembly, from here on out, it doesn't make sense, because GHC uses Core as a basis for compilation, *not* your code (it does your code as a basis for Core.) For completion's sake, the assembly, which is unexcitingly identical in both cases, is below. Note that the only thing interesting here is that safeHead' got translated to safeHeadzq, which is… well. Cute, and nothing else. Really though, if you're still at RWH, chapter three, it's Ok to be interested in these kinds of subtle performance differences, but you shouldn't concentrate on them. At this point, you can trust the compiler to optimize your code enough, and you can worry about performance if your program is actually slow. Happy Haskell hacking :-) Aleks Main_safeHeadzq_closure: .quad Main_safeHeadzq_info .text .align 8 .quad 0 .quad 32 se2_info: .Lcek: movq %rbx,%rax andq $7,%rax cmpq $2,%rax jae .Lcel movl $base_DataziMaybe_Nothing_closure+1,%ebx addq $8,%rbp jmp *0(%rbp) .Lcel: addq $16,%r12 cmpq 144(%r13),%r12 ja .Lces movq $base_DataziMaybe_Just_con_info,-8(%r12) movq 6(%rbx),%rax movq %rax,0(%r12) leaq -6(%r12),%rbx addq $8,%rbp jmp *0(%rbp) .Lces: movq $16,184(%r13) .Lceq: jmp *-16(%r13) .text .align 8 .quad 4294967301 .quad 0 .quad 15 Main_safeHead_closure: .quad Main_safeHead_info .text .align 8 .quad 0 .quad 32 seJ_info: .Lcf1: movq %rbx,%rax andq $7,%rax cmpq $2,%rax jae .Lcf2 movl $base_DataziMaybe_Nothing_closure+1,%ebx addq $8,%rbp jmp *0(%rbp) .Lcf2: addq $16,%r12 cmpq 144(%r13),%r12 ja .Lcf9 movq $base_DataziMaybe_Just_con_info,-8(%r12) movq 6(%rbx),%rax movq %rax,0(%r12) leaq -6(%r12),%rbx addq $8,%rbp jmp *0(%rbp) .Lcf9: movq $16,184(%r13) .Lcf7: jmp *-16(%r13) .text .align 8 .quad 4294967301 .quad 0 .quad 15

On Tuesday 07 June 2011, 10:33:08, Aleksandar Dimitrov wrote:
Note that the only thing interesting here is that safeHead' got translated to safeHeadzq, which is… well. Cute, and nothing else.
It's z-encoding, http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/SymbolNames Kind of irritating when you come across a z-encoded name containing a z where you don't expect z-encoding.

On Tue, Jun 07, 2011 at 10:59:26AM +0200, Daniel Fischer wrote:
On Tuesday 07 June 2011, 10:33:08, Aleksandar Dimitrov wrote:
Note that the only thing interesting here is that safeHead' got translated to safeHeadzq, which is… well. Cute, and nothing else.
It's z-encoding, http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/SymbolNames
Kind of irritating when you come across a z-encoded name containing a z where you don't expect z-encoding.
Well, that's outright adorable. I knew there had to be some systematic trickery behind this; thanks for sharing :-) Regards, Aleks

It's z-encoding, http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/SymbolNames
Kind of irritating when you come across a z-encoded name containing a z where you don't expect z-encoding.
I'm curious as to what you mean by "where you don't expect z-encoding." The assembly symbols would seem to 'qualify,' or do they turn up elsewhere as well?

On Wednesday 08 June 2011, 01:34:35, Arlen Christian Mart Cuss wrote:
It's z-encoding, http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/SymbolNam es
Kind of irritating when you come across a z-encoded name containing a z where you don't expect z-encoding.
I'm curious as to what you mean by "where you don't expect z-encoding." The assembly symbols would seem to 'qualify,' or do they turn up elsewhere as well?
Well, you'd expect it in the generated assembly, so you're prepared. I didn't expect z-encoded names in source files (in comments, of course). compiler/CgPrimOp.hs has a few pretty ones, e.g. -- #define unsafeFreezzeByteArrayzh(r,a) r=(a) emitPrimOp [res] UnsafeFreezeByteArrayOp [arg] _ = stmtC (CmmAssign (CmmLocal res) arg) -- #define sizzeofByteArrayzh(r,a) \ -- r = ((StgArrWords *)(a))->bytes emitPrimOp [res] SizeofByteArrayOp [arg] _ = stmtC $ CmmAssign (CmmLocal res) (cmmLoadIndexW arg fixedHdrSize bWord) so that caught me off guard. I particularly like sizzeof :D

-- #define sizzeofByteArrayzh(r,a) \ -- r = ((StgArrWords *)(a))->bytes emitPrimOp [res] SizeofByteArrayOp [arg] _ = stmtC $ CmmAssign (CmmLocal res) (cmmLoadIndexW arg fixedHdrSize bWord)
so that caught me off guard.
I particularly like sizzeof :D
Not looking forward to seeing a function like "sizzle" (sizzzzle?) make its way into the compiler :D :D
participants (3)
-
Aleksandar Dimitrov
-
Arlen Christian Mart Cuss
-
Daniel Fischer