TypePHP 编译器
https://swoole.com/aot/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
183 lines
4.2 KiB
183 lines
4.2 KiB
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
const BRIDGE_ITERATIONS = 10_000_000;
|
|
const BRIDGE_CONTAINER_ITERATIONS = 1_000_000;
|
|
const BRIDGE_ROUNDS = 5;
|
|
|
|
function bridgePureInt(int $iterations): int
|
|
{
|
|
$sum = 0;
|
|
for ($i = 0; $i < $iterations; $i++) {
|
|
$sum += $i * 2 + 1;
|
|
}
|
|
return $sum;
|
|
}
|
|
|
|
function bridgeAddOne(int $value): int
|
|
{
|
|
return $value + 1;
|
|
}
|
|
|
|
function bridgeFunctionCall(int $iterations): int
|
|
{
|
|
$sum = 0;
|
|
for ($i = 0; $i < $iterations; $i++) {
|
|
$sum += bridgeAddOne($i);
|
|
}
|
|
return $sum;
|
|
}
|
|
|
|
final class BridgeCalculator
|
|
{
|
|
public function hit(int $value): int
|
|
{
|
|
return $value + 1;
|
|
}
|
|
}
|
|
|
|
function bridgeMethodCall(int $iterations): int
|
|
{
|
|
$calculator = new BridgeCalculator();
|
|
$sum = 0;
|
|
for ($i = 0; $i < $iterations; $i++) {
|
|
$sum += $calculator->hit($i);
|
|
}
|
|
return $sum;
|
|
}
|
|
|
|
final class BridgeCounter
|
|
{
|
|
public int $value = 0;
|
|
}
|
|
|
|
function bridgePropertyAccess(int $iterations): int
|
|
{
|
|
$counter = new BridgeCounter();
|
|
for ($i = 0; $i < $iterations; $i++) {
|
|
$counter->value++;
|
|
}
|
|
return $counter->value;
|
|
}
|
|
|
|
final class BridgeMagicCall
|
|
{
|
|
public function __call(string $name, array $arguments): int
|
|
{
|
|
return $arguments[0] + 1;
|
|
}
|
|
}
|
|
|
|
function bridgeMagicCall(int $iterations): int
|
|
{
|
|
$object = new BridgeMagicCall();
|
|
$sum = 0;
|
|
for ($i = 0; $i < $iterations; $i++) {
|
|
$sum += $object->hit($i);
|
|
}
|
|
return $sum;
|
|
}
|
|
|
|
final class BridgeMagicProperty
|
|
{
|
|
private array $data = ['value' => 0];
|
|
|
|
public function __get(string $name): int
|
|
{
|
|
return $this->data[$name];
|
|
}
|
|
|
|
public function __set(string $name, mixed $value): void
|
|
{
|
|
$this->data[$name] = $value;
|
|
}
|
|
}
|
|
|
|
function bridgeMagicProperty(int $iterations): int
|
|
{
|
|
$object = new BridgeMagicProperty();
|
|
for ($i = 0; $i < $iterations; $i++) {
|
|
$object->value = $object->value + 1;
|
|
}
|
|
return $object->value;
|
|
}
|
|
|
|
function bridgeArrayAppend(int $iterations): int
|
|
{
|
|
$values = [];
|
|
for ($i = 0; $i < $iterations; $i++) {
|
|
$values[] = $i;
|
|
}
|
|
return count($values);
|
|
}
|
|
|
|
function bridgeStringConcat(int $iterations): string
|
|
{
|
|
$value = '';
|
|
for ($i = 0; $i < $iterations; $i++) {
|
|
$value .= 'x';
|
|
}
|
|
return $value;
|
|
}
|
|
|
|
function measureBridgeCase(string $case): array
|
|
{
|
|
$iterations = match ($case) {
|
|
'array_append', 'string_concat' => BRIDGE_CONTAINER_ITERATIONS,
|
|
default => BRIDGE_ITERATIONS,
|
|
};
|
|
$best = 0;
|
|
$bestResult = null;
|
|
for ($round = 0; $round < BRIDGE_ROUNDS; $round++) {
|
|
$start = hrtime(true);
|
|
$result = match ($case) {
|
|
'pure_int' => bridgePureInt($iterations),
|
|
'function_call' => bridgeFunctionCall($iterations),
|
|
'method_call' => bridgeMethodCall($iterations),
|
|
'property_access' => bridgePropertyAccess($iterations),
|
|
'magic_call' => bridgeMagicCall($iterations),
|
|
'magic_property' => bridgeMagicProperty($iterations),
|
|
'array_append' => bridgeArrayAppend($iterations),
|
|
'string_concat' => bridgeStringConcat($iterations),
|
|
default => throw new RuntimeException("Unknown benchmark case: {$case}"),
|
|
};
|
|
$elapsed = hrtime(true) - $start;
|
|
if ($round === 0 || $elapsed < $best) {
|
|
$best = $elapsed;
|
|
$bestResult = $result;
|
|
}
|
|
}
|
|
return [$best / $iterations, $bestResult];
|
|
}
|
|
|
|
function main(): void
|
|
{
|
|
bridgePureInt(1000);
|
|
bridgeFunctionCall(1000);
|
|
bridgeMethodCall(1000);
|
|
bridgePropertyAccess(1000);
|
|
bridgeMagicCall(1000);
|
|
bridgeMagicProperty(1000);
|
|
bridgeArrayAppend(1000);
|
|
bridgeStringConcat(1000);
|
|
|
|
$selectedCase = getenv('BRIDGE_CASE');
|
|
foreach ([
|
|
'pure_int',
|
|
'function_call',
|
|
'method_call',
|
|
'property_access',
|
|
'magic_call',
|
|
'magic_property',
|
|
'array_append',
|
|
'string_concat',
|
|
] as $case) {
|
|
if (is_string($selectedCase) && $selectedCase !== '' && $case !== $selectedCase) {
|
|
continue;
|
|
}
|
|
[$nanoseconds, $result] = measureBridgeCase($case);
|
|
printf("%s_ns=%.3f\n", $case, $nanoseconds);
|
|
printf("checksum_%s=%s\n", $case, is_string($result) ? strlen($result) : $result);
|
|
}
|
|
}
|
|
|