packages feed

kb-text-layout-0.1.0.0: bench/Bench.hs

module Main (main) where

import Control.DeepSeq (force)
import Control.Exception (evaluate)
import Test.Tasty.Bench (bcompare, bench, bgroup, defaultMain, nf, whnf, whnfIO)
import Text.Printf (printf)

import Demo qualified

import KB.Text.Layout.Break qualified as Break
import KB.Text.Layout.Measure qualified as Measure
import KB.Text.Shape qualified as TextShape

main :: IO ()
main =
  TextShape.withContext \shape -> do
    font <- TextShape.pushFontFromFile shape "demos/assets/NotoSans-Regular.ttf" 0
    ctx <- Measure.createLayoutContext shape
    body <- Measure.newStyle ctx font 1.0
    hyphenated <- evaluate (force (Demo.softHyphenate Demo.rivers))
    prepPlain <- Measure.prepare ctx body Demo.rivers
    prepHyph <- Measure.prepare ctx body hyphenated
    let
      atPx px = px / 11
      runAndMeasure layoutF prep w = (Break.layoutStats (layoutF prep w)).maxLineWidth
      vsGreedy = bcompare "$NF == \"greedy\""
    printf
      "%d segments plain, %d segments hyphenated\n"
      (length prepPlain.segments)
      (length prepHyph.segments)
    defaultMain
      [ bgroup
          "layout at 300px"
          [ bench "greedy" (whnf (runAndMeasure Break.layoutGreedy prepPlain) (atPx 300))
          , vsGreedy $ bench "greedy + hyphenation" (whnf (runAndMeasure Break.layoutGreedy prepHyph) (atPx 300))
          , vsGreedy $ bench "Knuth-Plass" (whnf (runAndMeasure Break.layoutOptimal prepPlain) (atPx 300))
          , vsGreedy $ bench "Knuth-Plass + hyphenation" (whnf (runAndMeasure Break.layoutOptimal prepHyph) (atPx 300))
          ]
      , bgroup
          "re-layout across widths"
          [ bench (name <> " " <> show px <> "px") (whnf (force layoutF prepPlain) (atPx (fromIntegral px)))
          | (name, layoutF) <- [("greedy", Break.layoutGreedy), ("Knuth-Plass", Break.layoutOptimal)]
          , px <- [150, 300, 600 :: Int]
          ]
      , bgroup
          "prepare (cached metrics)"
          [ bench "softHyphenate" (nf Demo.softHyphenate Demo.rivers)
          , bench "prepare plain" (whnfIO (Measure.prepare ctx body Demo.rivers))
          , bench "prepare hyphenated" (whnfIO (Measure.prepare ctx body hyphenated))
          ]
      ]