# LANGUAGE AllowAmbiguousTypes #
{-# LANGUAGE DataKinds           #-}
{-# LANGUAGE OverloadedStrings   #-}
# LANGUAGE ScopedTypeVariables #
# LANGUAGE TypeApplications     #

module CodecBench where

import           Control.Monad        (forM)
import           Criterion            (Benchmark, bench, bgroup, env, nf)
import qualified Data.ByteString.Lazy as BSL
import           Data.Word            (Word64)
import           HStream.Utils        (Encoder, EncoderType (..),
                                       deserializeHStreamRecords,
                                       serializeHStreamRecords)
import           Util

benchCodec :: [Benchmark]
benchCodec = encodeBench <> decodeBench

encodeBench :: [Benchmark]
encodeBench = [
  bgroup "origin encode" $
    map (\(size, describe) ->
          env (genHStreamRecords size) $ \records ->
            bench describe $ nf (serializeHStreamRecords @'OriginEncoder) records) testPair,

  bgroup "proto encode" $
    map (\(size, describe) ->
          env (genHStreamRecords size) $ \records ->
            bench describe $ nf (serializeHStreamRecords @'ProtoEncoder) records) testPair
 ]

decodeBench :: [Benchmark]
decodeBench = [
  bgroup "origin decode" $
    map (\(size, describe) ->
          env (genEncodedHStreamRecords @'OriginEncoder size) $ \records ->
            bench describe $ nf (deserializeHStreamRecords @'OriginEncoder) records) testPair,

  bgroup "proto decode" $
    map (\(size, describe) ->
          env (genEncodedHStreamRecords @'ProtoEncoder size) $ \records ->
            bench describe $ nf (deserializeHStreamRecords @'ProtoEncoder) records) testPair
 ]

getSize :: forall a. Encoder a => Int -> IO Word64
getSize size = fromIntegral . BSL.length <$> genEncodedHStreamRecords @a size

testCodecSize :: IO [(Word64, Word64)]
testCodecSize = do
  res1 <- forM testPair $ \(size, _) -> getSize @'OriginEncoder size
  res2 <- forM testPair $ \(size, _) -> getSize @'ProtoEncoder size
  return $ zip res1 res2


# LANGUAGE DataKinds           #
# LANGUAGE OverloadedStrings   #
# LANGUAGE AllowAmbiguousTypes #
# LANGUAGE ScopedTypeVariables #
# LANGUAGE TypeApplications     #

module CodecBench where

import           Control.Monad        (forM)
import           Criterion            (Benchmark, bench, bgroup, env, nf)
import qualified Data.ByteString.Lazy as BSL
import           Data.Word            (Word64)
import           HStream.Utils        (Encoder, EncoderType (..),
                                       deserializeHStreamRecords,
                                       serializeHStreamRecords)
import           Util

benchCodec :: [Benchmark]
benchCodec = encodeBench <> decodeBench

encodeBench :: [Benchmark]
encodeBench = [
  bgroup "origin encode" $
    map (\(size, describe) ->
          env (genHStreamRecords size) $ \records ->
            bench describe $ nf (serializeHStreamRecords @'OriginEncoder) records) testPair,

  bgroup "proto encode" $
    map (\(size, describe) ->
          env (genHStreamRecords size) $ \records ->
            bench describe $ nf (serializeHStreamRecords @'ProtoEncoder) records) testPair
 ]

decodeBench :: [Benchmark]
decodeBench = [
  bgroup "origin decode" $
    map (\(size, describe) ->
          env (genEncodedHStreamRecords @'OriginEncoder size) $ \records ->
            bench describe $ nf (deserializeHStreamRecords @'OriginEncoder) records) testPair,

  bgroup "proto decode" $
    map (\(size, describe) ->
          env (genEncodedHStreamRecords @'ProtoEncoder size) $ \records ->
            bench describe $ nf (deserializeHStreamRecords @'ProtoEncoder) records) testPair
 ]

getSize :: forall a. Encoder a => Int -> IO Word64
getSize size = fromIntegral . BSL.length <$> genEncodedHStreamRecords @a size

testCodecSize :: IO [(Word64, Word64)]
testCodecSize = do
  res1 <- forM testPair $ \(size, _) -> getSize @'OriginEncoder size
  res2 <- forM testPair $ \(size, _) -> getSize @'ProtoEncoder size
  return $ zip res1 res2

