From 3bcc039e7a61da99e4af1a8c9c6de600b84d7e1d Mon Sep 17 00:00:00 2001 From: Timo Tijhof Date: Thu, 27 Jul 2017 14:09:41 -0700 Subject: [PATCH] benchmarks: Add benchmarks for MapCacheLRU and HashBagOStuff Currently, HashBagOStuff leads in most benchmarks, except for the --fill benchmark, where MapCacheLRU is faster on HHVM. (by invoking with `PHP=hhvm mwscript maintenance/bench...`) Run in MediaWiki-Vagrant (Debian Jessie) on MacBook Pro host. $ benchmarkLruHash.php --count 50000 --construct Running PHP 5.6.30-0+deb8u1: - HashBagOStuff-construct (22% faster) total: 446.20ms (min: 0.01ms, median: 0.01ms, max: 2.09ms) - MapCacheLRU-construct total: 575.31ms (min: 0.01ms, median: 0.01ms, max: 3.51ms) Running PHP version 5.6.99-hhvm: - HashBagOStuff-construct (13% faster) total: 124.70ms (min: 0.00ms, median: 0.00ms, max: 1.27ms) - MapCacheLRU-construct total: 143.76ms (min: 0.00ms, median: 0.00ms, max: 2.01ms) For MapCacheLRU, the main slowdown is its use of Wikimedia\Assert. Removing that would make it faster than HashBagOStuff. $ benchmarkLruHash.php --count 3000 --fill Running PHP 5.6.30-0+deb8u1: - HashBagOStuff-fill (22% faster) total: 10196.82ms (min: 2.91ms, median: 3.24ms, max: 9.51ms) - MapCacheLRU-fill total: 13197.13ms (min: 3.92ms, median: 4.31ms, max: 9.90ms) Running PHP version 5.6.99-hhvm: - HashBagOStuff-fill total: 5700.37ms (min: 1.71ms, median: 1.85ms, max: 8.24ms) - MapCacheLRU-fill (11% faster) total: 4986.90ms (min: 1.48ms, median: 1.62ms, max: 6.93ms) Change-Id: Icd03f872dddb308f162c72674c8d2aa6092395e5 --- autoload.php | 1 + maintenance/benchmarks/benchmarkLruHash.php | 97 +++++++++++++++++++++ 2 files changed, 98 insertions(+) create mode 100644 maintenance/benchmarks/benchmarkLruHash.php diff --git a/autoload.php b/autoload.php index 510eeee699..2bf1d4cc5d 100644 --- a/autoload.php +++ b/autoload.php @@ -193,6 +193,7 @@ $wgAutoloadLocalClasses = [ 'BenchmarkDeleteTruncate' => __DIR__ . '/maintenance/benchmarks/bench_delete_truncate.php', 'BenchmarkHooks' => __DIR__ . '/maintenance/benchmarks/benchmarkHooks.php', 'BenchmarkJSMinPlus' => __DIR__ . '/maintenance/benchmarks/benchmarkJSMinPlus.php', + 'BenchmarkLruHash' => __DIR__ . '/maintenance/benchmarks/benchmarkLruHash.php', 'BenchmarkParse' => __DIR__ . '/maintenance/benchmarks/benchmarkParse.php', 'BenchmarkPurge' => __DIR__ . '/maintenance/benchmarks/benchmarkPurge.php', 'BenchmarkTidy' => __DIR__ . '/maintenance/benchmarks/benchmarkTidy.php', diff --git a/maintenance/benchmarks/benchmarkLruHash.php b/maintenance/benchmarks/benchmarkLruHash.php new file mode 100644 index 0000000000..1541f827fe --- /dev/null +++ b/maintenance/benchmarks/benchmarkLruHash.php @@ -0,0 +1,97 @@ +addDescription( 'Benchmarks HashBagOStuff and MapCacheLRU.' ); + $this->addOption( 'construct', 'Run construct only', false, false ); + $this->addOption( 'fill', 'Run fill only', false, false ); + } + + public function execute() { + $exampleKeys = []; + $max = 100; + $count = 500; + while ( $count-- ) { + $exampleKeys[] = wfRandomString(); + } + // 1000 keys (1...500, 500...1) + $keys = array_merge( $exampleKeys, array_reverse( $exampleKeys ) ); + + $fill = $this->hasOption( 'fill' ) || !$this->hasOption( 'construct' ); + $construct = $this->hasOption( 'construct' ) || !$this->hasOption( 'fill' ); + $benches = []; + + if ( $construct ) { + $benches['HashBagOStuff-construct'] = [ + 'function' => function () use ( $max ) { + $obj = new HashBagOStuff( [ 'maxKeys' => $max ] ); + }, + ]; + $benches['MapCacheLRU-construct'] = [ + 'function' => function () use ( $max ) { + $obj = new MapCacheLRU( $max ); + }, + ]; + } + + if ( $fill ) { + // For the fill bechmark, ensure object creation is not measured. + $hObj = null; + $benches['HashBagOStuff-fill'] = [ + 'setup' => function () use ( &$hObj, $max ) { + $hObj = new HashBagOStuff( [ 'maxKeys' => $max ] ); + }, + 'function' => function () use ( &$hObj, &$keys ) { + foreach ( $keys as $i => $key ) { + $hObj->set( $key, $i ); + } + } + ]; + $mObj = null; + $benches['MapCacheLRU-fill'] = [ + 'setup' => function () use ( &$mObj, $max ) { + $mObj = new MapCacheLRU( $max ); + }, + 'function' => function () use ( &$mObj, &$keys ) { + foreach ( $keys as $i => $key ) { + $mObj->set( $key, $i ); + } + } + ]; + } + + $this->bench( $benches ); + } +} + +$maintClass = BenchmarkLruHash::class; +require_once RUN_MAINTENANCE_IF_MAIN; -- 2.20.1