Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement pocketmine\world\format\SubChunk natively #24

Open
wants to merge 18 commits into
base: master
Choose a base branch
from

Conversation

dktapps
Copy link
Member

@dktapps dktapps commented Jul 30, 2021

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.

@dktapps
Copy link
Member Author

dktapps commented Jul 31, 2021

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

layer->container.collectGarbage(false, 0);

bool keep = false;
for (auto p : layer->container.getPalette()) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is stupid as per pmmp/PocketMine-MP#6574, although the impact here is less than in PHP

@dktapps
Copy link
Member Author

dktapps commented Dec 16, 2024

The serialize code should be simplified. I've always hated doing it this way. get_properties_for handler could probably do it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant