-
Notifications
You must be signed in to change notification settings - Fork 139
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rebased and fixed #347 #402
Conversation
* Make `(!?)` extract a value from the vector eagerly. * Make the range check for `(!?)` use one comparison instead of two.
and use it for all checks
Co-authored-by: konsumlamm <[email protected]>
Co-authored-by: konsumlamm <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's great that you were able to confirm that this trick works!
Sorry for not mentioning this earlier, but wouldn't it be more efficient to directly index in the v !? i | i `inRange` length v = basicUnsafeIndexM v i
| otherwise = Nothing It's possible that the allocation of the |
Note that class (MVector (Mutable v) a) => Vector v a where
...
basicUnsafeIndexM :: v a -> Int -> Box a
... and -- | /O(1)/ Unsafe indexing without bounds checking.
unsafeIndex :: Vector v a => v a -> Int -> a
{-# INLINE_FUSED unsafeIndex #-}
unsafeIndex v i = checkIndex Unsafe i (length v) $ unBox (basicUnsafeIndexM v i) in favor of |
Huh, apparently this was changed a while ago in #335. Ignore my comment, then. |
And I should also apologize that I should've mentioned this earlier, but I was afraid a function like factorial :: HasCallStack => Int -> Mod1097
factorial n
| n < 0 = error "factorial: pole of Gamma function"
| n >= VU.length factorials = error "factorial: out of desired range"
| otherwise = factorials VU.! n
factorials :: VU.Vector Mod1097
factorials = VU.scanl' (*) (M1097 1) $ VU.generate 300000 (M1097 . fromIntegral . (+1))
-- | Remainder ring mod 10^9+7.
newtype Mod1097 = M1097 Word32
deriving newtype (Eq, Show, VGM.MVector VUM.MVector, VG.Vector VU.Vector, VUM.Unbox)
newtype instance VU.Vector Mod1097 = UnboxMod1097 (VU.Vector Word32)
newtype instance VUM.MVector s Mod1097 = UnboxMMod1097 (VUM.MVector s Word32)
instance Num Mod1097 where ... Anyway, I'll try this and check how it goes. If it goes wrong, I'll inform you all in a separate issue. |
@konsumlamm Yes it has been changed in order to allow GND/DerivingVia since GHC cannot coerce between @gksato I think GHC is rather good at cutting away such allocations. But please do report your findings |
Allocations? I meant comparisons. |
Ah! I wonder if GHC is able to remove duplicate checks even without such trick |
# Changes in version 0.13.0.0 * `mkType` from `Data.Vector.Generic` is deprecated in favor of `Data.Data.mkNoRepType` * The role signatures on several `Vector` types were too permissive, so they have been tightened up: * The role signature for `Data.Vector.Mutable.MVector` is now `type role MVector nominal representational` (previously, both arguments were `phantom`). [#224](haskell/vector#224) * The role signature for `Data.Vector.Primitive.Vector` is now `type role Vector nominal` (previously, it was `phantom`). The role signature for `Data.Vector.Primitive.Mutable.MVector` is now `type role MVector nominal nominal` (previously, both arguments were `phantom`). [#316](haskell/vector#316) * The role signature for `Data.Vector.Storable.Vector` is now `type role Vector nominal` (previous, it was `phantom`), and the signature for `Data.Vector.Storable.Mutable.MVector` is now `type role MVector nominal nominal` (previous, both arguments were `phantom`). [#235](haskell/vector#235) We pick `nominal` for the role of the last argument instead of `representational` since the internal structure of a `Storable` vector is determined by the `Storable` instance of the element type, and it is not guaranteed that the `Storable` instances between two representationally equal types will preserve this internal structure. One consequence of this choice is that it is no longer possible to `coerce` between `Storable.Vector a` and `Storable.Vector b` if `a` and `b` are nominally distinct but representationally equal types. We now provide `unsafeCoerce{M}Vector` and `unsafeCast` functions to allow this (the onus is on the user to ensure that no `Storable` invariants are broken when using these functions). * Methods of type classes `Data.Vector.Generic.Mutable.MVector` and `Data.Vector.Generic.Vector` use concrete monads (`ST`, etc) istead of being polymorphic (`PrimMonad`, etc). [#335](haskell/vector#335). This makes it possible to derive `Unbox` with: * `GeneralizedNewtypeDeriving` * via `UnboxViaPrim` and `Prim` instance * via `As` and `IsoUnbox` instance: [#378](haskell/vector#378) * Add `MonadFix` instance for boxed vectors: [#312](haskell/vector#312) * Re-export `PrimMonad` and `RealWorld` from mutable vectors: [#320](haskell/vector#320) * Add `maximumOn` and `minimumOn`: [#356](haskell/vector#356) * The functions `scanl1`, `scanl1'`, `scanr1`, and `scanr1'` for immutable vectors are now defined when given empty vectors as arguments, in which case they return empty vectors. This new behavior is consistent with the one of the corresponding functions in `Data.List`. Prior to this change, applying an empty vector to any of those functions resulted in an error. This change was introduced in: [#382](haskell/vector#382) * Change allocation strategy for `unfoldrN`: [#387](haskell/vector#387) * Remove `CPP` driven error reporting in favor of `HasCallStack`: [#397](haskell/vector#397) * Remove redundant `Storable` constraints on to/from `ForeignPtr` conversions: [#394](haskell/vector#394) * Add `unsafeCast` to `Primitive` vectors: [#401](haskell/vector#401) * Make `(!?)` operator strict: [#402](haskell/vector#402) * Add `readMaybe`: [#425](haskell/vector#425) * Add `groupBy` and `group` for `Data.Vector.Generic` and the specialized version in `Data.Vector`, `Data.Vector.Unboxed`, `Data.Vector.Storable` and `Data.Vector.Primitive`. [#427](haskell/vector#427) * Add `toArraySlice` and `unsafeFromArraySlice` functions for conversion to and from the underlying boxed `Array`: [#434](haskell/vector#434)
This is rebased #347 updated to work with current master.
indexM
strict in vector by usingbasicIndexM