Skip to content

Instantly share code, notes, and snippets.

@matipojo
Created December 26, 2024 09:27
Show Gist options
  • Select an option

  • Save matipojo/f425185ad12d9cc628163120f2b99640 to your computer and use it in GitHub Desktop.

Select an option

Save matipojo/f425185ad12d9cc628163120f2b99640 to your computer and use it in GitHub Desktop.
<?php
class CommentsVsConstantsPerformanceTest {
const ITERATIONS = 1000000;
const WARMUP_ROUNDS = 3;
const TEST_FILES = [
'raw' => 'raw_values.php',
'constants' => 'constants.php'
];
private function createTestFiles(): void {
// Create file with raw values
$rawCode = <<<'EOD'
<?php
function processUserRaw() {
// User status codes
// 0 = inactive
// 1 = active
// 2 = suspended
// 3 = pending
$status = 1;
// Maximum login attempts
$maxAttempts = 3;
// Default timeout in seconds
$timeout = 1800;
// Account types
// 'free' = Free tier
// 'pro' = Professional tier
// 'enterprise' = Enterprise tier
$accountType = 'pro';
if ($status === 1 && $maxAttempts > 0) {
return $accountType === 'pro' ? $timeout * 2 : $timeout;
}
return null;
}
EOD;
file_put_contents(self::TEST_FILES['raw'], $rawCode);
// Create file with constants
$constantsCode = <<<'EOD'
<?php
class UserConfig {
const STATUS_INACTIVE = 0;
const STATUS_ACTIVE = 1;
const STATUS_SUSPENDED = 2;
const STATUS_PENDING = 3;
const MAX_LOGIN_ATTEMPTS = 3;
const SESSION_TIMEOUT_SECONDS = 1800;
const ACCOUNT_FREE = 'free';
const ACCOUNT_PRO = 'pro';
const ACCOUNT_ENTERPRISE = 'enterprise';
}
function processUserConstants() {
$status = UserConfig::STATUS_ACTIVE;
$maxAttempts = UserConfig::MAX_LOGIN_ATTEMPTS;
$timeout = UserConfig::SESSION_TIMEOUT_SECONDS;
$accountType = UserConfig::ACCOUNT_PRO;
if ($status === UserConfig::STATUS_ACTIVE && $maxAttempts > 0) {
return $accountType === UserConfig::ACCOUNT_PRO ?
$timeout * 2 : $timeout;
}
return null;
}
EOD;
file_put_contents(self::TEST_FILES['constants'], $constantsCode);
}
private function clearCache(): void {
if (function_exists('opcache_reset')) {
opcache_reset();
}
}
private function measureFileCompilation(string $filename): float {
$this->clearCache();
$start = microtime(true);
include $filename;
$end = microtime(true);
return $end - $start;
}
private function measureExecution(callable $callback): float {
// Warmup phase
for ($i = 0; $i < self::WARMUP_ROUNDS; $i++) {
$callback();
}
$start = microtime(true);
for ($i = 0; $i < self::ITERATIONS; $i++) {
$callback();
}
$end = microtime(true);
return $end - $start;
}
public function runComparison(): void {
// Create test files
$this->createTestFiles();
// Measure compilation times
$rawCompileTime = $this->measureFileCompilation(self::TEST_FILES['raw']);
$constantsCompileTime = $this->measureFileCompilation(self::TEST_FILES['constants']);
// Measure execution times
$rawExecutionTime = $this->measureExecution('processUserRaw');
$constantsExecutionTime = $this->measureExecution('processUserConstants');
// Calculate totals
$rawTotal = $rawCompileTime + $rawExecutionTime;
$constantsTotal = $constantsCompileTime + $constantsExecutionTime;
// Print results
echo "Performance Comparison Results:\n";
echo str_repeat("=", 60) . "\n";
echo "Raw Values Approach:\n";
echo sprintf(" Compilation Time: %.6f seconds\n", $rawCompileTime);
echo sprintf(" Execution Time: %.6f seconds\n", $rawExecutionTime);
echo sprintf(" Total Time: %.6f seconds\n", $rawTotal);
echo str_repeat("-", 60) . "\n";
echo "Constants Approach:\n";
echo sprintf(" Compilation Time: %.6f seconds\n", $constantsCompileTime);
echo sprintf(" Execution Time: %.6f seconds\n", $constantsExecutionTime);
echo sprintf(" Total Time: %.6f seconds\n", $constantsTotal);
echo str_repeat("=", 60) . "\n";
// Calculate and display differences
$compileDiff = $constantsCompileTime - $rawCompileTime;
$executionDiff = $constantsExecutionTime - $rawExecutionTime;
$totalDiff = $constantsTotal - $rawTotal;
echo "\nPerformance Analysis:\n";
echo sprintf("Compilation Difference: %+.6f seconds\n", $compileDiff);
echo sprintf("Execution Difference: %+.6f seconds\n", $executionDiff);
echo sprintf("Total Difference: %+.6f seconds\n", $totalDiff);
echo "\nAnalysis Summary:\n";
echo "1. Compilation Impact:\n";
echo " - Constants approach " . ($compileDiff > 0 ? "takes longer" : "is faster") . " to compile\n";
echo " - Difference is " . number_format(abs($compileDiff * 1000000), 2) . " microseconds\n";
echo "\n2. Execution Impact:\n";
echo " - Constants approach " . ($executionDiff > 0 ? "takes longer" : "is faster") . " to execute\n";
echo " - Difference is " . number_format(abs($executionDiff * 1000000), 2) . " microseconds\n";
// Cleanup test files
unlink(self::TEST_FILES['raw']);
unlink(self::TEST_FILES['constants']);
}
}
// Run the test
$test = new CommentsVsConstantsPerformanceTest();
$test->runComparison();
@matipojo
Copy link
Author

Performance Comparison Results:
============================================================
Raw Values Approach:
  Compilation Time: 0.000080 seconds
  Execution Time:   0.085303 seconds
  Total Time:       0.085383 seconds
------------------------------------------------------------
Constants Approach:
  Compilation Time: 0.000059 seconds
  Execution Time:   0.086738 seconds
  Total Time:       0.086797 seconds
============================================================

Performance Analysis:
Compilation Difference:  -0.000021 seconds
Execution Difference:    +0.001435 seconds
Total Difference:        +0.001414 seconds

Analysis Summary:
1. Compilation Impact:
   - Constants approach is faster to compile
   - Difference is 20.74 microseconds

2. Execution Impact:
   - Constants approach takes longer to execute
   - Difference is 1,435.04 microseconds

@eyalmrejen-elementor
Copy link

It's very interesting, and obviously, lookup time has a price, but it's extremely negligible. This is not about efficiency but rather ease of maintenance. Most of the time, we maintain the code rather than write it—the easier it is to understand, the better.
In the next dev talk I will talk about this with regards to refactoring. Come to the meeting, I hope u will find it interesting.
Coding is hard, and reading code requires a lot of cognitive load, so I aim to help with that in my comment. It's a bigger issue, and I am ready to open it up some more.
But comments are still considered a code smell, and this is one of the pillars of Clean Code. The University teaches us to write comments, while the industry, with its savoir-faire, takes a different approach. At the end, when we understand all the issues, it boils down to style—clean code rules are basically a style.
P.s
Your amazing code does not take into account statistical caching that happens in runtime, as all interpreted languages have.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment