Skip to content

Instantly share code, notes, and snippets.

@hastinbe
Created October 27, 2025 20:28
Show Gist options
  • Select an option

  • Save hastinbe/d6ec020c019131c7490623ea217d6755 to your computer and use it in GitHub Desktop.

Select an option

Save hastinbe/d6ec020c019131c7490623ea217d6755 to your computer and use it in GitHub Desktop.
<?php
require __DIR__.'/vendor/autoload.php';
set_time_limit(600);
$app = require_once __DIR__.'/bootstrap/app.php';
$app->make(\Illuminate\Contracts\Console\Kernel::class)->bootstrap();
use Statamic\Facades\Stache;
use Statamic\Facades\Entry;
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Helper\FormatterHelper;
class StacheOptimizationTest
{
public function __construct(
protected ConsoleOutput $output,
protected FormatterHelper $formatter
) {}
private function line(string $message): void { $this->output->writeln($message); }
private function comment(string $message): void { $this->output->writeln("<comment>{$message}</comment>"); }
private function error(string $message): void { $this->output->writeln("<error>{$message}</error>"); }
private function success(string $message): void { $this->output->writeln("<fg=green;options=bold>✓ {$message}</>"); }
private function timedOperation(callable $callback, string $action): array
{
$this->comment("{$action}...");
$start = microtime(true);
$memoryStart = memory_get_peak_usage();
$callback();
$stats = [
'time' => (microtime(true) - $start) * 1000,
'memory' => memory_get_peak_usage() - $memoryStart,
];
$this->success("{$action} completed in " . $this->formatter->formatTime($stats['time'] / 1000));
return $stats;
}
private function verifyQueries(): int
{
$this->comment('Verifying indexes...');
$queries = [
'All entries' => fn() => Entry::query()->count(),
'Published entries' => fn() => Entry::query()->where('published', true)->count(),
];
$passed = 0;
foreach ($queries as $name => $query) {
try {
$count = $query();
$this->success("{$name}: {$count} entries");
$passed++;
} catch (\Throwable $e) {
$this->error("{$name} failed: {$e->getMessage()}");
}
}
return $passed;
}
private function displaySummary(array $stats, int $entries, int $queriesPassed, int $queryCount): void
{
$this->line('');
$this->line($this->formatter->formatSection('Results', 'Performance Summary'));
$this->line('');
(new Table($this->output))
->setHeaders(['Metric', 'Value'])
->setRows([
['Warm time', '<info>' . $this->formatter->formatTime($stats['time'] / 1000) . '</info>'],
['Peak memory', '<info>' . $this->formatter->formatMemory($stats['memory']) . '</info>'],
['Files processed', '<info>' . Stache::fileCount() . '</info>'],
['Queries verified', $queriesPassed === $queryCount ? '<fg=green>✓ All passed</>' : '<fg=yellow>⚠ Some failed</>'],
['Total entries', '<info>' . $entries . '</info>'],
])
->setStyle('box-double')
->render();
}
public function run(): int
{
$this->line('');
$this->line($this->formatter->formatSection('Stache Optimization Test', 'Running performance analysis...'));
$this->line('');
$entryCount = Entry::query()->count();
$this->line("→ Found <info>{$entryCount}</info> entries");
if ($entryCount === 0) {
$this->error("\n✗ No entries found. Aborting test.");
return 1;
}
$this->line('');
$this->timedOperation(fn() => Stache::clear(), 'Clearing Stache');
$this->line('');
$warmStats = $this->timedOperation(fn() => Stache::warm(), 'Warming Stache');
$this->output->writeln("<fg=yellow> ! Peak memory: " . $this->formatter->formatMemory($warmStats['memory']) . "</>");
$this->line('');
$queriesPassed = $this->verifyQueries();
$this->displaySummary($warmStats, $entryCount, $queriesPassed, 2);
$this->line('');
$this->success('Test complete!');
return 0;
}
}
$test = new StacheOptimizationTest(new ConsoleOutput(), new FormatterHelper());
try {
exit($test->run());
} catch (\Throwable $e) {
$test->error("{$e->getMessage()} in {$e->getFile()} on line {$e->getLine()}");
exit(1);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment