1#!/usr/bin/php
2<?php
3declare(strict_types=1);
4
5// Avatar parameters
6define('IMG_SIZE', 120);
7define('ROUNDS', 30000);
8define('PARTS_DIR', __DIR__ . '/parts');
9
10$partGroups = [
11    'arms'  => 5,
12    'body'  => 15,
13    'eyes'  => 15,
14    'hair'  => 5,
15    'legs'  => 5,
16    'mouth' => 10,
17];
18
19function getRandomPart(string $group, int $max): GdImage {
20    $n = random_int(1, $max);
21    $path = sprintf('%s/%s_%d.png', PARTS_DIR, $group, $n);
22    return imagecreatefrompng($path);
23}
24
25function generateMonster(): GdImage {
26    $img = imagecreatetruecolor(IMG_SIZE, IMG_SIZE);
27    imagesavealpha($img, true);
28    $transparent = imagecolorallocatealpha($img, 0, 0, 0, 127);
29    imagefill($img, 0, 0, $transparent);
30
31    global $partGroups;
32    foreach ($partGroups as $group => $count) {
33        $part = getRandomPart($group, $count);
34        imagecopy($img, $part, 0, 0, 0, 0, IMG_SIZE, IMG_SIZE);
35        imagedestroy($part);
36    }
37    return $img;
38}
39
40// Start timing
41$start = microtime(true);
42
43// Run benchmark
44$sizes = [];
45for ($i = 0; $i < ROUNDS; $i++) {
46    $img = generateMonster();
47    ob_start();
48    imagepng($img, null, 9);
49    $data = ob_get_clean();
50    $sizes[] = strlen($data);
51    imagedestroy($img);
52}
53
54// End timing
55$end = microtime(true);
56$elapsed = $end - $start;
57
58// Statistics
59$min = min($sizes);
60$max = max($sizes);
61$avg = array_sum($sizes) / count($sizes);
62$stddev = sqrt(array_sum(array_map(fn($s) => pow($s - $avg, 2), $sizes)) / count($sizes));
63
64printf("Generated avatars: %d\n", ROUNDS);
65printf("Minimum size: %.2f KB\n", $min / 1024);
66printf("Maximum size: %.2f KB\n", $max / 1024);
67printf("Average size: %.2f KB\n", $avg / 1024);
68printf("Standard deviation: %.2f KB\n", $stddev / 1024);
69printf("Elapsed time: %.2f seconds\n", $elapsed);
70printf("Avatars per second: %.2f\n", ROUNDS / $elapsed);
71