Наиболее эффективный способ преобразования Data.ByteString.Lazy в CStringLen - PullRequest
1 голос
/ 15 февраля 2020

Мне нужно закодировать некоторые данные в JSON, а затем pu sh - в системный журнал, используя hsyslog. Типы двух соответствующих функций:

Aeson.encode :: a -> Data.ByteString.Lazy.ByteString

System.Posix.Syslog.syslog :: Maybe Facility
                           -> Priority
                           -> CStringLen
                           -> IO () 

Какой самый эффективный способ (скорость и память) конвертировать Lazy.ByteString -> CStringLen? Я нашел Data.ByteString.Unsafe, но он работает только с ByteString, а не Lazy.ByteString?

Должен ли я просто вставить unsafeUseAsCStringLen . Data.String.Conv.toS и назвать его днем? Будет ли это правильно с эффективностью?

1 Ответ

1 голос
/ 15 февраля 2020

Думаю, я бы использовал Data.ByteString.Lazy.toStrict вместо toS, чтобы избежать дополнительной зависимости от пакета.

В любом случае, вы не найдете ничего более эффективного, чем:

unsafeUseAsCStringLen (toStrict lbs) $ \cstrlen -> ...

В общем, toStrict - это «дорогая» операция, потому что ленивый ByteString обычно состоит из группы «кусков», каждый из которых состоит из строгого ByteString и не обязательно еще загружается в память. Функция toStrict должна принудительно помещать все строгие блоки ByteString в память и гарантировать, что они будут скопированы в один непрерывный блок, как требуется для строгого ByteString до применения без копирования unsafeUseAsCStringLen.

Однако toStrict оптимально обрабатывает ленивый ByteString, состоящий из одного фрагмента без копирования.

На практике aeson использует эффективный Data.ByteString.Builder для создайте JSON, и если JSON будет достаточно маленьким (я думаю, что меньше 4k), он создаст ленивый ByteString с одним фрагментом. В этом случае toStrict - это нулевая копия, а unsafeUseAsCStringLen - нулевая копия, и вся операция в основном бесплатна.

Но учтите, что в вашем приложении, где вы передаете строку в syslogger, беспокоясь об эффективности этой операции, это безумие. Полагаю, вам понадобятся тысячи операций копирования, чтобы хоть как-то повлиять на эффективность всего действия.

...