166 lines
3.7 KiB
PHP
166 lines
3.7 KiB
PHP
<?php
|
|
|
|
namespace SMW\Tests\Benchmark;
|
|
|
|
use RuntimeException;
|
|
use SMW\DataValues\PropertyValue;
|
|
use SMW\DIProperty;
|
|
use SMW\Query\Parser as QueryParser;
|
|
use SMW\Query\PrintRequest;
|
|
use SMW\Store;
|
|
use SMWQuery as Query;
|
|
|
|
/**
|
|
* @group semantic-mediawiki-benchmark
|
|
*
|
|
* @license GPL-2.0-or-later
|
|
* @since 2.5
|
|
*
|
|
* @author mwjames
|
|
*/
|
|
class QueryBenchmarkRunner implements BenchmarkReporter {
|
|
|
|
/**
|
|
* @var Store
|
|
*/
|
|
private $store;
|
|
|
|
/**
|
|
* @var QueryParser
|
|
*/
|
|
private $queryParser;
|
|
|
|
/**
|
|
* @var Benchmarker
|
|
*/
|
|
private $benchmarker;
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
private $benchmarkReport = [];
|
|
|
|
/**
|
|
* @since 2.5
|
|
*
|
|
* @param Store $store
|
|
* @param QueryParser $queryParser
|
|
* @param Benchmarker $benchmarker
|
|
*/
|
|
public function __construct( Store $store, QueryParser $queryParser, Benchmarker $benchmarker ) {
|
|
$this->store = $store;
|
|
$this->queryParser = $queryParser;
|
|
$this->benchmarker = $benchmarker;
|
|
}
|
|
|
|
/**
|
|
* @since 2.5
|
|
*
|
|
* @param array
|
|
*/
|
|
public function getBenchmarkReport() {
|
|
return $this->benchmarkReport;
|
|
}
|
|
|
|
/**
|
|
* @since 2.5
|
|
*
|
|
* @param array $case
|
|
*/
|
|
public function run( array $case ) {
|
|
$this->benchmarkReport = [];
|
|
$this->benchmarker->clear();
|
|
|
|
if ( !isset( $case['query'] ) && !is_array( $case['query'] ) ) {
|
|
throw new RuntimeException( 'Query specification is not available.' );
|
|
}
|
|
|
|
if ( !isset( $case['repetitionCount'] ) ) {
|
|
throw new RuntimeException( 'repetitionCount is not available.' );
|
|
}
|
|
|
|
$start = microtime( true );
|
|
$queryReports = [];
|
|
|
|
$queryReports['count'] = $this->doQuery(
|
|
$case, $this->createQuery( $case, Query::MODE_COUNT )
|
|
);
|
|
|
|
$queryReports['instance'] = $this->doQuery(
|
|
$case, $this->createQuery( $case, Query::MODE_INSTANCES )
|
|
);
|
|
|
|
$this->benchmarkReport = [
|
|
'type' => $case['type'],
|
|
'note' => $case['query']['condition'] . ( isset( $case['note'] ) ? ' (' . $case['note'] . ')' : '' ),
|
|
'query' => $queryReports,
|
|
'time' => microtime( true ) - $start
|
|
];
|
|
}
|
|
|
|
private function doQuery( array $case, $query ) {
|
|
$this->benchmarker->clear();
|
|
|
|
$memoryBefore = memory_get_peak_usage( false );
|
|
|
|
for ( $i = 0; $i < $case['repetitionCount']; $i++ ) {
|
|
|
|
$start = microtime( true );
|
|
|
|
$queryResult = $this->store->getQueryResult( $query );
|
|
|
|
$this->benchmarker->addBenchmarkPoint( microtime( true ) - $start );
|
|
}
|
|
|
|
$count = $query->querymode === Query::MODE_COUNT ? $queryResult->getCountValue() : $queryResult->getCount();
|
|
$columnCount = $queryResult->getColumnCount();
|
|
|
|
return [
|
|
'rowCount' => $count,
|
|
'columnCount' => $columnCount,
|
|
'repetitionCount' => $case['repetitionCount'],
|
|
"memory" => memory_get_peak_usage( false ) - $memoryBefore,
|
|
"time" => [
|
|
'sum' => $this->benchmarker->getSum(),
|
|
'mean' => $this->benchmarker->getMean(),
|
|
'sd' => $this->benchmarker->getStandardDeviation(),
|
|
'norm' => $this->benchmarker->getNormalizedValueBy( $case['repetitionCount'] )
|
|
]
|
|
];
|
|
}
|
|
|
|
private function createQuery( array $case, $mode, array $printouts = [] ) {
|
|
$description = $this->queryParser->getQueryDescription(
|
|
$case['query']['condition']
|
|
);
|
|
|
|
foreach ( $case['query']['printouts'] as $printout ) {
|
|
$property = DIProperty::newFromUserLabel( $printout );
|
|
|
|
$propertyValue = new PropertyValue( '__pro' );
|
|
$propertyValue->setDataItem( $property );
|
|
|
|
$description->addPrintRequest(
|
|
new PrintRequest( PrintRequest::PRINT_PROP, null, $propertyValue )
|
|
);
|
|
}
|
|
|
|
$query = new Query(
|
|
$description
|
|
);
|
|
|
|
$query->setUnboundlimit(
|
|
isset( $case['query']['parameters']['limit'] ) ? $case['query']['parameters']['limit'] : 500
|
|
);
|
|
|
|
$query->setOffset(
|
|
isset( $case['query']['parameters']['offset'] ) ? $case['query']['parameters']['offset'] : 0
|
|
);
|
|
|
|
$query->setQueryMode( $mode );
|
|
|
|
return $query;
|
|
}
|
|
|
|
}
|