Implement pocketmine\world\format\SubChunk natively
Since SubChunk is final (or should be), there's clear bounds on its functionality.
Since all the types of its fields are also sealed, we can safely assume that the PHP method wrappers of PalettedBlockArray and LightArray won't be overridden. This means it's possible to avoid calling hot methods like PalettedBlockArray::get() via the Zend VM, and instead directly call their C++ counterparts without going through PHP. This eliminates 1 function call for hot functions like SubChunk::getFullBlock() and SubChunk::setFullBlock().
A quick performance test using this code:
<?php
declare(strict_types=1);
$extensionUsed = class_exists(\pocketmine\world\format\SubChunk::class, false);
echo "Extension used: " . ($extensionUsed ? "YES" : "NO") . "\n";
require 'vendor/autoload.php';
function test() : void{
$palette = new \pocketmine\world\format\SubChunk(1, []);
for($x = 0; $x < 16; ++$x){
for($z = 0; $z < 16; ++$z){
for($y = 0; $y < 16; ++$y){
$palette->setFullBlock($x, $y, $z, ord("0"));
}
}
}
$loops = 10000;
$val = 0;
$start = hrtime(true);
for($i = 0; $i < $loops; ++$i){
for($x = 0; $x < 16; ++$x){
for($z = 0; $z < 16; ++$z){
for($y = 0; $y < 16; ++$y){
$val += $palette->getFullBlock($x, $y, $z);
}
}
}
}
echo "Time: " . number_format((hrtime(true) - $start) / ($loops * 4096)) . "ns/op\n";
}
test();
yields the following results on Windows, PHP 8.0.8 (release), JIT=off:
Extension used: YES
Time: 53ns/op
compared to:
Extension used: NO
Time: 130ns/op
This shows a performance improvement of approximately 60%, with throughput improved by 2.5x.
I think this is now functionally OK, but it needs to be thoroughly covered by tests before merge.
The following things should be tested:
- [ ] All public methods
- [ ] Cloning
- [ ] Serialize/unserialize
- [ ] Garbage collection of empty palettes