From 62ea075549e42e6b3a62267f03958607a228e59a Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Thu, 13 Aug 2026 21:22:01 +0600 Subject: [PATCH] updated & fixed ops/tech issues --- CONTRIBUTING.md | 11 ++++ benchmarks/ReleaseWorkloadsBench.php | 82 ++++++++++---------------- benchmarks/stress/ReleaseStress.php | 88 ++++++++++++++++++++++++++++ 3 files changed, 130 insertions(+), 51 deletions(-) create mode 100644 benchmarks/stress/ReleaseStress.php diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ad81ec1..b977119 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -140,6 +140,17 @@ composer ic:bench:quick composer ic:bench:chart ``` +The default PHPForge commands intentionally exclude release stress workloads. +Run those explicitly, with their declared single-revolution settings: + +```bash +vendor/bin/phpbench run benchmarks/stress/ReleaseStress.php --bootstrap=vendor/autoload.php +``` + +The 10,000-job file-queue subject is a limit-finding workload and can take +several minutes. It must not be combined with the quick suite's global +revolution and iteration overrides. + Performance claims must include reproducible before-and-after results from comparable environments. Avoid conclusions based on a single unstable run. Add or update benchmark coverage when existing benchmarks do not represent the changed execution path. diff --git a/benchmarks/ReleaseWorkloadsBench.php b/benchmarks/ReleaseWorkloadsBench.php index 4e1fee0..df91d41 100644 --- a/benchmarks/ReleaseWorkloadsBench.php +++ b/benchmarks/ReleaseWorkloadsBench.php @@ -43,27 +43,12 @@ public function tearDown(): void public function benchChunkAssembly100(): void { - $this->benchmarkChunkAssembly(100); - } - - public function benchChunkAssembly1000ReverseArrival(): void - { - $this->benchmarkChunkAssembly(1_000, true); + $this->runChunkAssembly(100); } public function benchQueue100(): void { - $this->benchmarkQueue(100); - } - - public function benchQueue1000(): void - { - $this->benchmarkQueue(1_000); - } - - public function benchQueue10000(): void - { - $this->benchmarkQueue(10_000); + $this->runQueueWorkload(100); } public function benchReader128KiB(): void @@ -83,35 +68,51 @@ public function benchReader8KiB(): void public function benchSyncChecksum1000Files(): void { - $this->benchmarkSync(SyncComparison::CHECKSUM); + $this->runSyncWorkload(SyncComparison::CHECKSUM); } public function benchSyncSize1000Files(): void { - $this->benchmarkSync(SyncComparison::SIZE); + $this->runSyncWorkload(SyncComparison::SIZE); } public function benchSyncSizeAndModifiedTime1000Files(): void { - $this->benchmarkSync(SyncComparison::SIZE_AND_MODIFIED_TIME); + $this->runSyncWorkload(SyncComparison::SIZE_AND_MODIFIED_TIME); } - public function benchTransactionHundredUpdates(): void + public function benchTransactionOneUpdate(): void { - $this->benchmarkTransaction(100); + $this->runTransactionWorkload(1); } - public function benchTransactionOneUpdate(): void + public function benchTransactionTenUpdates(): void { - $this->benchmarkTransaction(1); + $this->runTransactionWorkload(10); } - public function benchTransactionTenUpdates(): void + private function consumeReader(int $chunkSize): void + { + $this->createLargeFile(); + foreach ((new SafeFileReader($this->largeFile))->chunks($chunkSize) as $chunk) { + strlen($chunk); + } + + $download = new DownloadProcessor(); + $download->setChunkSize($chunkSize); + $output = fopen('php://temp', 'w+b'); + if (is_resource($output)) { + $download->streamDownload($this->largeFile, $output); + fclose($output); + } + } + + private function createLargeFile(): void { - $this->benchmarkTransaction(10); + FlysystemHelper::write($this->largeFile, str_repeat('0123456789abcdef', 512 * 1024)); } - private function benchmarkChunkAssembly(int $chunks, bool $reverse = false): void + private function runChunkAssembly(int $chunks, bool $reverse = false): void { $uploadDirectory = PathHelper::join($this->baseDirectory, 'uploads-' . $chunks); $temporaryDirectory = PathHelper::join($this->baseDirectory, 'chunks-' . $chunks); @@ -134,7 +135,7 @@ private function benchmarkChunkAssembly(int $chunks, bool $reverse = false): voi $uploader->finalizeChunkUpload("bench_{$chunks}"); } - private function benchmarkQueue(int $jobs): void + private function runQueueWorkload(int $jobs): void { $queue = new FileJobQueue(PathHelper::join($this->baseDirectory, "queue-{$jobs}.json"), maxJobs: $jobs); for ($index = 0; $index < $jobs; $index++) { @@ -143,7 +144,7 @@ private function benchmarkQueue(int $jobs): void $queue->process(static function (): void {}); } - private function benchmarkSync(SyncComparison $comparison): void + private function runSyncWorkload(SyncComparison $comparison): void { FlysystemHelper::createDirectory($this->sourceDirectory); for ($index = 0; $index < 1_000; $index++) { @@ -156,7 +157,7 @@ private function benchmarkSync(SyncComparison $comparison): void (new DirectoryOperations($this->sourceDirectory))->syncTo($target, true, null, $comparison); } - private function benchmarkTransaction(int $updates): void + private function runTransactionWorkload(int $updates): void { $this->createLargeFile(); $path = PathHelper::join($this->baseDirectory, "transaction-{$updates}.bin"); @@ -167,25 +168,4 @@ private function benchmarkTransaction(int $updates): void } }); } - - private function consumeReader(int $chunkSize): void - { - $this->createLargeFile(); - foreach ((new SafeFileReader($this->largeFile))->chunks($chunkSize) as $chunk) { - strlen($chunk); - } - - $download = new DownloadProcessor(); - $download->setChunkSize($chunkSize); - $output = fopen('php://temp', 'w+b'); - if (is_resource($output)) { - $download->streamDownload($this->largeFile, $output); - fclose($output); - } - } - - private function createLargeFile(): void - { - FlysystemHelper::write($this->largeFile, str_repeat('0123456789abcdef', 512 * 1024)); - } } diff --git a/benchmarks/stress/ReleaseStress.php b/benchmarks/stress/ReleaseStress.php new file mode 100644 index 0000000..cf8112e --- /dev/null +++ b/benchmarks/stress/ReleaseStress.php @@ -0,0 +1,88 @@ +baseDirectory = PathHelper::join(sys_get_temp_dir(), 'pathwise_release_stress_' . uniqid('', true)); + } + + public function tearDown(): void + { + if (FlysystemHelper::directoryExists($this->baseDirectory)) { + FlysystemHelper::deleteDirectory($this->baseDirectory); + } + } + + public function benchChunkAssembly1000ReverseArrival(): void + { + $uploadDirectory = PathHelper::join($this->baseDirectory, 'uploads'); + $temporaryDirectory = PathHelper::join($this->baseDirectory, 'chunks'); + $uploader = new UploadProcessor(); + $uploader->setDirectorySettings($uploadDirectory, false, $temporaryDirectory); + for ($index = 999; $index >= 0; $index--) { + $part = PathHelper::join($this->baseDirectory, "part-{$index}.tmp"); + FlysystemHelper::write($part, 'x'); + $uploader->processChunkUpload([ + 'error' => UPLOAD_ERR_OK, + 'size' => 1, + 'tmp_name' => $part, + 'name' => basename($part), + ], 'stress_1000', $index, 1_000, 'assembled.txt'); + } + $uploader->finalizeChunkUpload('stress_1000'); + } + + public function benchQueue1000(): void + { + $this->runQueueWorkload(1_000); + } + + public function benchQueue10000(): void + { + $this->runQueueWorkload(10_000); + } + + public function benchTransactionHundredUpdates(): void + { + $path = PathHelper::join($this->baseDirectory, 'transaction-100.bin'); + FlysystemHelper::write($path, str_repeat('0123456789abcdef', 512 * 1024)); + (new FileOperations($path))->transaction(static function (FileOperations $operations): void { + for ($index = 0; $index < 100; $index++) { + $operations->update(str_repeat((string) ($index % 10), 8 * 1024 * 1024)); + } + }); + } + + private function runQueueWorkload(int $jobs): void + { + $queue = new FileJobQueue(PathHelper::join($this->baseDirectory, "queue-{$jobs}.json"), maxJobs: $jobs); + for ($index = 0; $index < $jobs; $index++) { + $queue->enqueue('benchmark', ['index' => $index]); + } + $queue->process(static function (): void {}); + } +}