По соображениям производительности мне хотелось бы получить нулевое копирование ByteString (строгое, на данный момент) до Vector. Поскольку Vector является просто a ByteArray# под капотом, а ByteString является ForeignPtr, это может выглядеть примерно так:
caseBStoVector :: ByteString -> Vector a
caseBStoVector (BS fptr off len) =
withForeignPtr fptr $ \ptr -> do
let ptr' = plusPtr ptr off
p = alignPtr ptr' (alignment (undefined :: a))
barr = ptrToByteArray# p len -- I want this function, or something similar
barr' = ByteArray barr
alignI = minusPtr p ptr
size = (len-alignI) `div` sizeOf (undefined :: a)
return (Vector 0 size barr')
Это, конечно, неправильно. Даже с отсутствующей функцией ptrToByteArray# это, похоже, необходимо избежать ptr вне области withForeignPtr. Итак, мои вопросы:
-
Это сообщение, вероятно, рекламирует мое примитивное понимание
ByteArray#, если кто-то может немного рассказать оByteArray#, его представлении, о том, как он управляется (GCed) и т.д. Я был бы благодарен. -
Тот факт, что
ByteArray#живет на куче GCed иForeignPtrявляется внешним, кажется, является фундаментальной проблемой - все операции доступа различны. Возможно, мне стоит взглянуть на переопределениеVectorиз= ByteArray !Int !Intна что-то с другой косвенностью? Кто-то вроде= Location !Int !Intгдеdata Location = LocBA ByteArray | LocFPtr ForeignPtrи предоставляет операции обертывания для обоих этих типов? Это косвенное воздействие может сильно ухудшить производительность. -
Не вступая в брак с этими двумя вместе, возможно, я могу просто получить доступ к произвольным типам элементов в
ForeignPtrболее эффективным образом. Кто-нибудь знает библиотеку, которая рассматриваетForeignPtr(илиByteString) как массив произвольных типовStorableилиPrimitive? Это все равно потеряет меня слиянием потока и настройкой из пакета Vector.