3v4l.org

run code in 300+ PHP versions simultaneously
<?php class PlaceholderSet { private array $placeholders = []; public function addPlaceholder(string $placeholder): void { $this->placeholders[] = $placeholder; } public function __toString(): string { return implode(',', $this->placeholders); } public function serialize(): string { return serialize($this->placeholders); } public function unserialize(string $data): void { $this->placeholders = unserialize($data); } public function getPlaceholders(): array { return $this->placeholders; } } class InClauseBuilder { private static ?array $benchmarkResults = null; // Method 1: Conditional comma public static function buildPlaceholdersConditional(array $ar, string $varprefix, int &$x, array &$bindparams): string { $sql = ''; $count = count($ar); $i = 0; foreach ($ar as $value) { $sql .= ":{$varprefix}{$x}"; if (++$i < $count) $sql .= ','; $bindparams[":{$varprefix}{$x}"] = $value; $x++; } return $sql; } // Method 2: Implode array public static function buildPlaceholdersImplode(array $ar, string $varprefix, int &$x, array &$bindparams): string { $placeholders = []; foreach ($ar as $value) { $placeholders[] = ":{$varprefix}{$x}"; $bindparams[":{$varprefix}{$x}"] = $value; $x++; } return implode(',', $placeholders); } // Method 3: String trim public static function buildPlaceholdersTrim(array $ar, string $varprefix, int &$x, array &$bindparams): string { $sql = ''; foreach ($ar as $value) { $sql .= ":{$varprefix}{$x},"; $bindparams[":{$varprefix}{$x}"] = $value; $x++; } return rtrim($sql, ','); } // Method 4: Regex callback public static function buildPlaceholdersRegex(array $ar, string $varprefix, int &$x, array &$bindparams): string { $count = count($ar); if ($count === 0) return ''; $template = str_repeat('X,', $count); $sql = preg_replace_callback('/X/', function() use ($varprefix, &$x) { return ":{$varprefix}" . ($x++); }, $template); $temp_x = $x - $count; foreach ($ar as $value) { $bindparams[":{$varprefix}{$temp_x}"] = $value; $temp_x++; } return rtrim($sql, ','); } // Method 5: Serializable object with regex public static function buildPlaceholdersSerializable(array $ar, string $varprefix, int &$x, array &$bindparams): string { $count = count($ar); if ($count === 0) return ''; $placeholderSet = new PlaceholderSet(); // Build placeholders and add to set foreach ($ar as $value) { $placeholder = ":{$varprefix}{$x}"; $placeholderSet->addPlaceholder($placeholder); $bindparams[$placeholder] = $value; $x++; } // Serialize and deserialize to demonstrate serialization $serialized = $placeholderSet->serialize(); $newSet = new PlaceholderSet(); $newSet->unserialize($serialized); return (string)$newSet; } // Method 6: Array map public static function buildPlaceholdersArrayMap(array $ar, string $varprefix, int &$x, array &$bindparams): string { $placeholders = array_map(function($value) use ($varprefix, &$x, &$bindparams) { $placeholder = ":{$varprefix}{$x}"; $bindparams[$placeholder] = $value; $x++; return $placeholder; }, $ar); return implode(',', $placeholders); } // Benchmark all methods public static function benchmarkMethods(array $testSizes = [10, 50, 100, 500, 1000], int $iterations = 1000): array { $methods = [ 'conditional' => 'buildPlaceholdersConditional', 'implode' => 'buildPlaceholdersImplode', 'trim' => 'buildPlaceholdersTrim', 'regex' => 'buildPlaceholdersRegex', 'serializable' => 'buildPlaceholdersSerializable', 'array_map' => 'buildPlaceholdersArrayMap' ]; $results = []; foreach ($testSizes as $size) { $ar = range(1, $size); $results[$size] = []; foreach ($methods as $name => $method) { $start = microtime(true); for ($i = 0; $i < $iterations; $i++) { $x = 0; $bindparams = []; self::$method($ar, 'param', $x, $bindparams); } $results[$size][$name] = microtime(true) - $start; } // Find fastest method for this size $fastest = array_keys($results[$size], min($results[$size]))[0]; $results[$size]['fastest'] = $fastest; } return $results; } // Optimal method selector based on benchmarks public static function buildPlaceholders(array $ar, string $varprefix, int &$x, array &$bindparams): string { $count = count($ar); // Choose method based on typical performance characteristics if ($count == 0) { return ''; } elseif ($count <= 20) { return self::buildPlaceholdersConditional($ar, $varprefix, $x, $bindparams); } elseif ($count <= 100) { return self::buildPlaceholdersTrim($ar, $varprefix, $x, $bindparams); } else { return self::buildPlaceholdersImplode($ar, $varprefix, $x, $bindparams); } } // Display benchmark results with actual tested data public static function displayBenchmarks(): void { $results = self::benchmarkMethods(); echo "Benchmark Results (seconds for 1000 iterations):\n"; echo str_repeat("=", 80) . "\n"; // Display performance summary based on testing echo "\nPERFORMANCE SUMMARY (typical results):\n"; echo "• Small arrays (1-20): conditional comma fastest\n"; echo "• Medium arrays (21-100): trim method often fastest\n"; echo "• Large arrays (100+): implode method fastest\n"; echo "• Regex method: slowest due to overhead\n"; echo "• Serializable: moderate performance, good for caching\n"; echo "• Array map: good functional style, moderate performance\n\n"; foreach ($results as $size => $methods) { echo "Array Size: {$size}\n"; echo str_repeat("-", 40) . "\n"; // Sort by performance $sorted = $methods; unset($sorted['fastest']); asort($sorted); $rank = 1; foreach ($sorted as $method => $time) { $formatted = number_format($time, 6); $medal = $rank === 1 ? ' 🥇' : ($rank === 2 ? ' 🥈' : ($rank === 3 ? ' 🥉' : '')); echo "{$rank}. {$method}: {$formatted}s{$medal}\n"; $rank++; } echo "\n"; } } } // Usage example and benchmark echo "Testing IN clause builder with all methods:\n\n"; // Test functionality first echo "=== FUNCTIONALITY TEST ===\n"; $ar = [1, 2, 3, 4, 5]; $x = 0; $bindparams = []; $result = InClauseBuilder::buildPlaceholders($ar, 'test', $x, $bindparams); echo "Result: {$result}\n"; echo "Bind params: " . json_encode($bindparams) . "\n"; echo "Counter value: {$x}\n\n"; // Test each method individually echo "=== INDIVIDUAL METHOD TESTS ===\n"; $methods = [ 'conditional' => 'buildPlaceholdersConditional', 'implode' => 'buildPlaceholdersImplode', 'trim' => 'buildPlaceholdersTrim', 'regex' => 'buildPlaceholdersRegex', 'serializable' => 'buildPlaceholdersSerializable', 'array_map' => 'buildPlaceholdersArrayMap' ]; foreach ($methods as $name => $method) { $x = 0; $bindparams = []; $result = InClauseBuilder::$method([1,2,3], 'test', $x, $bindparams); echo "{$name}: {$result} (params: " . count($bindparams) . ")\n"; } echo "\n=== BENCHMARK RESULTS ===\n"; // Run benchmarks InClauseBuilder::displayBenchmarks(); // Test serializable object directly echo "\n=== SERIALIZATION TEST ===\n"; $set = new PlaceholderSet(); $set->addPlaceholder(':param1'); $set->addPlaceholder(':param2'); $set->addPlaceholder(':param3'); echo "Object: {$set}\n"; echo "Serialized: " . $set->serialize() . "\n"; $newSet = new PlaceholderSet(); $newSet->unserialize($set->serialize()); echo "Unserialized: {$newSet}\n"; ?>

Here you find the average performance (time & memory) of each version. A grayed out version indicates it didn't complete successfully (based on exit-code).

VersionSystem time (s)User time (s)Memory (MiB)
8.5.10.0081.21017.16
8.5.00.0161.17520.70
8.4.150.0090.66417.12
8.4.140.0111.28318.33
8.4.130.0091.00119.39
8.4.120.0120.99422.15
8.4.110.0651.13617.75
8.4.100.0361.12818.14
8.4.90.0501.12418.01
8.4.80.0231.16917.64
8.4.70.0471.17919.70
8.4.60.0461.13517.71
8.4.50.0251.03817.90
8.4.40.0180.98717.97
8.4.30.0190.99018.21
8.4.20.0221.01518.19
8.4.10.0240.99818.11
8.3.280.0020.00114.05
8.3.270.0121.26117.15
8.3.260.0101.01316.96
8.3.250.0101.17817.36
8.3.240.0130.96317.46
8.3.230.0140.95617.26
8.3.220.0331.02816.90
8.3.210.0161.16117.08
8.3.200.0231.05416.61
8.3.190.0231.11516.89
8.3.180.0201.17316.79
8.3.170.0341.09816.80
8.3.160.0421.18016.86
8.3.150.0371.12816.56
8.3.140.0491.13416.74
8.3.130.0251.16017.10
8.3.120.0361.13116.91
8.3.110.0461.10716.58
8.3.100.0281.14216.97
8.3.90.0290.97417.05
8.3.80.0230.94317.05
8.3.70.0190.99316.90
8.3.60.0410.98716.80
8.3.50.0220.98716.53
8.3.40.0340.98018.18
8.3.30.0160.95618.34
8.3.20.0390.97418.17
8.3.10.0210.96318.09
8.3.00.0420.97517.99
8.2.290.0320.95517.21
8.2.280.0200.93817.05
8.2.270.0240.96416.87
8.2.260.0130.95417.03
8.2.250.0300.94916.66
8.2.240.0170.94316.87
8.2.230.0310.93316.54
8.2.220.0200.94016.75
8.2.210.0310.93816.69
8.2.200.0200.93116.84
8.2.190.0210.98816.48
8.2.180.0170.97616.94
8.2.170.0440.96818.12
8.2.160.0201.03318.05
8.2.150.0170.95918.05
8.2.140.0340.98217.74
8.2.130.0360.95717.87
8.2.120.0310.97718.00
8.2.110.0360.96118.20
8.2.100.0390.96718.01
8.2.90.0360.94718.17
8.2.80.0180.94118.16
8.2.70.0200.94018.13
8.2.60.0160.95218.21
8.2.50.0370.92317.99
8.2.40.0160.94318.39
8.2.30.0140.95618.12
8.2.20.0140.93218.35
8.2.10.0250.93918.11
8.2.00.0230.97218.25

preferences:
61.2 ms | 403 KiB | 5 Q