From 6ee14873bc2b907d4072c980ea062537b064cf8a Mon Sep 17 00:00:00 2001 From: hadestructhor <60148800+hadestructhor@users.noreply.github.com> Date: Thu, 9 Jan 2025 02:10:18 +0100 Subject: [PATCH] feat: benchmark init [SKIP CI] --- README.md | 30 +++++++- benchmark.md | 4 ++ benchmark.nu | 68 +++++++++++++++++++ build_results/bun-rspack-dockerfile.csv | 2 + build_results/nginx-distroless-dockerfile.csv | 2 + 5 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 benchmark.md create mode 100644 benchmark.nu create mode 100644 build_results/bun-rspack-dockerfile.csv create mode 100644 build_results/nginx-distroless-dockerfile.csv diff --git a/README.md b/README.md index 4dfb550..7131acb 100644 --- a/README.md +++ b/README.md @@ -289,6 +289,20 @@ This is the biggest optimization in image size to date! A 1 998,2 MB less than I personally love distroless images. I've seen people say that you can debug them less, and not having basic tools like a shell is contraining, but I personally think it's not needed. You can simply build both a distroless and alpine image of your same code, then when there's a need to debug, scitch the container image for the alpine version. Or even better, use distroless images in production environments and alpines in development environments. +### Benchmark of build times using docker build --no-cache + +Here's the link to the result of the benchmark made to recreate the image 100 times for each branch that contains each optimization: +[benchmark.md](./benchmark.md) + +The nushell script used to generate this benchmark is [benchmark.nu](./benchmark.nu). + +You can execute the following command to run the build 100 times on each branch: +```shell +nu benchmark.nu 100 +``` + +By default the script runs 5 builds. + # Français @@ -578,4 +592,18 @@ Et voici la taille des images juste ici : C'est la plus grosse optimisation de taille jusqu'à présent ! Une différence de 1 998,2 MB de moins que l'image original, c'est 63,83 fois plus petit!!! C'est une réduction folle de 98,43% ! Et le meilleur dans tout ça? L'application est beaucoup plus sécurisé !!!!! Personnellement j'adore les images distroless. J'ai vu certaines personnes dire qu'elles sont moins débuggable en n'ayant aucun outil basique comme un bash mais je pense que ce n'est pas nécessaire. -Vous pouvez tout simplement construire une image alpine et distroless de votre application, puis remplacer votre image distroless par l'alpine pour débugger en cas de bug. Ou encore mieux et ce que je fais personnelelement, utiliser une image alpine en environnement de développement et distroless en production. \ No newline at end of file +Vous pouvez tout simplement construire une image alpine et distroless de votre application, puis remplacer votre image distroless par l'alpine pour débugger en cas de bug. Ou encore mieux et ce que je fais personnelelement, utiliser une image alpine en environnement de développement et distroless en production. + +## Benchmark temps de build avec docker build --no-cache + +Voici le lien du benchmark réalisé pour chaque branche en lançant la construction des conteneurs 100 fois: +[benchmark.md](./benchmark.md) + +Le script nushell pour générer ce benchmark se trouve dans [benchmark.nu](./benchmark.nu) + +Vous pouvez l'exécuter en lançant la commande suivante, pour lancer 100 build de chaque docker: +```shell +nu benchmark.nu 100 +``` + +Par défaut le script lance 5 build de chaque image. \ No newline at end of file diff --git a/benchmark.md b/benchmark.md new file mode 100644 index 0000000..083ed62 --- /dev/null +++ b/benchmark.md @@ -0,0 +1,4 @@ +| tag | image | image size | median_time | max_time | min_time | benchmark_size | +| --------------------------- | ---------------------- | ---------- | ----------------------- | ----------------------- | ----------------------- | -------------- | +| bun-rspack-dockerfile | react-bun-rspack | 66.5MB | 9sec 220ms 258µs 900ns | 9sec 220ms 258µs 900ns | 9sec 220ms 258µs 900ns | 1 | +| nginx-distroless-dockerfile | react-nginx-distroless | 31.8MB | 9sec 221ms 865µs 600ns | 9sec 221ms 865µs 600ns | 9sec 221ms 865µs 600ns | 1 | \ No newline at end of file diff --git a/benchmark.nu b/benchmark.nu new file mode 100644 index 0000000..a419149 --- /dev/null +++ b/benchmark.nu @@ -0,0 +1,68 @@ +def main [benchmark_size:int=5] -> table { +mkdir build_results +let bench = [ + ['tag', 'image']; + ['simple-dockerfile', 'react-simple'], + ['multi-stage-dockerfile', 'react-multistage'], + ['node-alpine-dockerfile', 'react-multistage-alpine'], + ['nginx-dockerfile', 'react-nginx'], + ['nginx-alpine-dockerfile', 'react-nginx-alpine'], + ['bun-rspack-dockerfile', 'react-bun-rspack'], + ['nginx-distroless-dockerfile', 'react-nginx-distroless'] + ] + + let images = [ + 'node:18', + 'node:18-alpine' + 'nginx', + 'nginx:stable-alpine', + 'oven/bun', + 'cgr.dev/chainguard/nginx' + ] + + echo 'Pulling all docker images in advance' + echo '' + + for entry in $images { + docker pull $entry + echo '' + } + echo '' + + mut benchmark: table = [] + + for entry: record in $bench { + echo $'Switching to branch ($entry.tag)' + echo '' + git checkout $entry.tag + mut sum = 0ns + mut max = 0ns + mut min = 0ns + mut json_result = [] + for i in 1..$benchmark_size { + let time = $'(timeit {docker build --no-cache -t $entry.image .})' | into duration + $sum += $time + + if $max == 0ns or $time >= $max { + $max = $time + } + if $min == 0ns or $time <= $min { + $min = $time + } + $json_result = ($json_result ++ [['tag', 'image', 'time']; [$entry.tag, $entry.image, $time]]) + } + let row table = [ + ['tag', 'image', 'image size', 'median_time', 'max_time', 'min_time', 'benchmark_size']; + [$'($entry.tag)', $'($entry.image)', $"(docker image ls $entry.image | from ssv | get 0 | get SIZE)", ($sum / $benchmark_size), $max, $min, $benchmark_size] + ] + $benchmark = ($benchmark ++ $row) + echo $json_result + $json_result | to csv | save -f $'./build_results/($entry.tag).csv' + } + + git checkout main + $benchmark | to md --pretty | save -f benchmark.md + git commit -m $"updated README for benchmarks (date now | format date) [CI SKIP]" + git push + return $benchmark +} diff --git a/build_results/bun-rspack-dockerfile.csv b/build_results/bun-rspack-dockerfile.csv new file mode 100644 index 0000000..8bdaf23 --- /dev/null +++ b/build_results/bun-rspack-dockerfile.csv @@ -0,0 +1,2 @@ +tag,image,time +bun-rspack-dockerfile,react-bun-rspack,9sec 220ms 258µs 900ns diff --git a/build_results/nginx-distroless-dockerfile.csv b/build_results/nginx-distroless-dockerfile.csv new file mode 100644 index 0000000..62658c3 --- /dev/null +++ b/build_results/nginx-distroless-dockerfile.csv @@ -0,0 +1,2 @@ +tag,image,time +nginx-distroless-dockerfile,react-nginx-distroless,9sec 221ms 865µs 600ns