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 |