Насколько «небезопасными» являются Data.Vector unsafeFreeze / unsafeThaw? - PullRequest
0 голосов
/ 04 января 2019

Документация для Data.Vector.unsafeFreeze гласит:

Небезопасное преобразование изменяемого вектора в неизменяемый без копирования. Изменяемый вектор не может использоваться после этой операции.

Я бы хотел охарактеризовать, что именно здесь означает «небезопасный». Экспериментально представляется, что «только» подразумевает, что дальнейшая модификация исходного изменчивого вектора приведет к тому, что неизменяемый вектор (ы), возвращаемый unsafeFreeze, перестанет быть чистым:

$ import qualified Data.Vector as V
$ import qualified Data.Vector.Mutable as MV
$ import Control.Monad.ST
$ :{
$ |runST $ do
$ |        mv <- V.thaw $ V.fromList [0..10]
$ |        v <- V.unsafeFreeze mv
$ |        MV.write mv 0 (-1)
$ |        MV.write mv 1 (-2)
$ |        v' <- V.freeze mv
$ |        v'' <- V.unsafeFreeze mv
$ |        return (v, v', v'')
$ |:}
([-1,-2,2,3,4,5,6,7,8,9,10],[-1,-2,2,3,4,5,6,7,8,9,10],[-1,-2,2,3,4,5,6,7,8,9,10])

Я могу представить себе модификацию источника, используемого в «небезопасной» заморозке, для выполнения всевозможных гнусных вещей, которые могут привести к гораздо худшему поведению, например, segfaulting. Я быстро из моей глубины К сожалению, попытка прочитать источник об опасных операциях.

Могу ли я рассчитывать на то, что указанная примесь является единственным способом, которым эти операции являются "небезопасными"?

Для контекста: мне нужно реализовать различные модифицирующие алгоритмы в типично неизменяемой структуре данных, и отказ от повторного использования его общедоступного API в рамках этой области внутренней изменчивости был бы чрезвычайно неудобен (так как AFAICT не существует способа для общего применения) доступ как изменяемые, так и неизменные векторы). (Ab) использование unsafeFreeze, когда мне нужно будет использовать этот API, будет идеальным запасным люком, если я не буду настраивать себя на гораздо более неприятные побочные эффекты в будущем.

1 Ответ

0 голосов
/ 04 января 2019

Этот шаблон использования может привести к сбою: см. Это сообщение для справки. Причина в том, что мутирование неизменяемого массива может создать минорные корни GC, которые фактически не видны для минорных GC. Эта ошибка возникает только в том случае, если ваш массив находится в старом поколении GC, а записанные объекты - в новом поколении, поэтому вы не будете запускать его с помощью самых простых тестов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...