Haskell GPGME намного медленнее подписывает, чем GPG
Моя программа использует GPG для подписи файлов. Я использую GPGME в Haskell, и проблема в том, что он примерно в 16 раз медленнее, чем при использовании GPG из командной строки. Вот пример:
Код Haskell:
module Main where
import qualified Data.ByteString as B
import qualified Crypto.Gpgme as Gpg
main :: IO ()
main = do
fileContents <- B.readFile "randomfile"
eitherSigned <- sign fileContents
case eitherSigned of
Left err -> print err
Right signed ->
B.writeFile "signedfile" signed
sign :: B.ByteString -> IO (Either [Gpg.InvalidKey] B.ByteString)
sign bs =
let
sign' :: Gpg.Ctx -> IO (Either [Gpg.InvalidKey] Gpg.Plain)
sign' ctx = Gpg.sign ctx [] Gpg.Normal bs
in
Gpg.withCtx "/home/t/.gnupg" "C" Gpg.OpenPGP sign'
Я создаю ненужный 10 МБ файл с
$ dd if=/dev/zero of=randomfile bs=10000000 count=1
Я подписываю это с помощью GPG из командной строки:
$ time gpg -s randomfile
и получить
gpg -s randomfile 0.14s user 0.00s system 99% cpu 0.136 total
Я подписываю его с моей программой на Haskell
$ time stack exec hasksign
и получить
stack exec hasksign 0.27s user 0.07s system 14% cpu 2.239 total
Я попытался снова запустить код на Haskell с профилированием и получил такой результат:
hasksign +RTS -p -RTS randomfile
total time = 2.21 secs (2208 ticks @ 1000 us, 1 processor)
total alloc = 115,627,312 bytes (excludes profiling overheads)
COST CENTRE MODULE SRC %time %alloc
newCtx Crypto.Gpgme.Ctx src/Crypto/Gpgme/Ctx.hs:(21,1)-(51,21) 77.0 0.0
signIntern Crypto.Gpgme.Crypto src/Crypto/Gpgme/Crypto.hs:(310,1)-(354,14) 20.4 8.6
collectResult.go.\ Crypto.Gpgme.Internal src/Crypto/Gpgme/Internal.hs:(29,21)-(34,46) 2.1 81.9
main Main src/Main.hs:(7,1)-(13,43) 0.1 8.7
Я посмотрел в функции newCtx, где тратится время, но мне не ясно, что стоит так дорого.