-
Notifications
You must be signed in to change notification settings - Fork 18
Description
Situation
Currently, the instances Enum Int64
and Enum Word64
conditionally compile like this:
#if WORD_SIZE_IN_BITS < 64
-- See Note [Stable Unfolding for list producers] in GHC.Enum
{-# INLINE enumFrom #-}
enumFrom = integralEnumFrom
-- See Note [Stable Unfolding for list producers] in GHC.Enum
{-# INLINE enumFromThen #-}
enumFromThen = integralEnumFromThen
-- See Note [Stable Unfolding for list producers] in GHC.Enum
{-# INLINE enumFromTo #-}
enumFromTo = integralEnumFromTo
-- See Note [Stable Unfolding for list producers] in GHC.Enum
{-# INLINE enumFromThenTo #-}
enumFromThenTo = integralEnumFromThenTo
#else
-- See Note [Stable Unfolding for list producers] in GHC.Enum
{-# INLINE enumFrom #-}
enumFrom = boundedEnumFrom
-- See Note [Stable Unfolding for list producers] in GHC.Enum
{-# INLINE enumFromThen #-}
enumFromThen = boundedEnumFromThen
#endif
So, it uses a slow Integer
-based fallback on 32-bit platforms.
Motivation
Now two things have happened that might make use reevaluate this decision:
- GHC is getting a JavaScript back end which uses 32-bit words.
- I have recently implemented code generation for 64-bit operations in the i386 back end (!10771).
So 32-bit platforms will become more common and there is now more performance to gain on i386.
Concrete Changes
I propose to write custom Enum Int64
and Enum Word64
instances that use native operations instead of falling back to Integer
-based operations. Essentially, this means copying the implementation of Enum Int
and Enum Word
and replacing all occurrences of Int
with Int64
and the same for Word
.
Implementation
I've already implemented the required changes in !10825.
Impact
This is purely a performance change. I expect it will almost always have a positive impact on performance, but it might cause things to inline differently. I have done benchmarks for i386 which shows a 1.5x performance improvement and also for JS which shows a 5.6x performance improvement.
One other impact is that this adds a bit of maintenance burden on the GHC developers. But this part of the code has been very stable, so we don't expect this to be a problem.
Alternatives
-
Keep status quo. This means bad performance.
-
Reduce duplication using
CPP
trickery. This makes it harder to navigate the source code.