Я хочу представить строку длиной до 120 бит, и скорость имеет решающее значение. Мне нужно иметь возможность построить битовую строку с помощью повторяющихся операций snoc
, а затем использовать ее с помощью повторяющихся операций uncons
. Одна идея состоит в том, чтобы украсть реализацию Word128
из data-dword
и использовать что-то вроде этого для сборки:
empty = 1
snoc xs x = (xs `shiftL` 1) .|. x
Но unconsing, кажется, становится немного уродливым, поскольку сначала нужно countLeadingZeros
и сдвинуть влево, чтобы устранить их, прежде чем можно будет считать элементы, сдвигая и маскируя старшие биты.
Есть ли какой-то более приятный способ, который, по крайней мере, такой же быстрый, или какой-то более быстрый способ, который не слишком неприятный?
Контекст
Фил Раффвинд предложил версию at
lens
для Data.Map
, но все реализации до сих пор существенно медленнее, чем наивная реализация lens
, используемая в настоящее время, когда сравнение ключей дешево. Если бы я мог создать очень дешевое представление пути к записи при ее поиске, а затем очень эффективно использовать его с помощью специализированной версии insert
или delete
, тогда, возможно, я мог бы сделать это стоящим.
Word128
в кольцевой буфер? Просто сохраните индекс головы и хвоста вашей очереди. - person Daniel Wagner   schedule 02.05.2016countLeadingZeros
будет самым быстрым, просто обязательно используйтеunsafeShift
и избегайтеtestBit
иsetBit
(вместо этого переосуществите использование небезопасных сдвигов). - person András Kovács   schedule 02.05.2016clz
. - person András Kovács   schedule 03.05.2016ctz
быстрее дляuncons
с двумя словами, но, конечно, также возможно, что виноват мой код. Работать с двумя словами больно. Я не уверен, что есть хороший способ справиться с переносчиками. - person dfeuer   schedule 03.05.2016