Speed up Data.Char.isDigit
isDigit
is currently defined like this:
isDigit :: Char -> Bool
isDigit c = c >= '0' && c <= '9'
This will short-circuit the right way if you're looking for digits mixed with spaces, but the wrong way if you're looking for digits mixed with letters. It also requires a conditional jump to do that short-circuiting (confirmed by inspecting the assembly). It should be better to use an unsigned comparison instead:
isDigit :: Char -> Bool
isDigit c = (fromIntegral (ord c) :: Word) - 48 <= 9
The interesting section looks like this
movq 7(%rbx),%rax
addq $-48,%rax
cmpq $9,%rax
setbe %al
movzbl %al,%eax
shlq $3,%rax
movq ghczmprim_GHCziTypes_Bool_closure_tbl(%rax),%rbx
addq $8,%rbp
jmp *(%rbp)
or like this with -fllvm:
movq 7(%rbx), %rax
addq $-48, %rax
cmpq $10, %rax
sbbq %rax, %rax
andq $8, %rax
movq ghczmprim_GHCziTypes_Bool_closure_tbl(%rax), %rbx
movq 8(%rbp), %rax
addq $8, %rbp
jmpq *%rax # TAILCALL
Trac metadata
Trac field | Value |
---|---|
Version | 7.9 |
Type | FeatureRequest |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |