3declare(strict_types=1);
9$options = getopt(
'', [
'fixture:',
'mysql:',
'pgsql:',
'source:',
'build',
'runs:',
'random:',
'results:',
'expect:',
'reconnect']);
10if (count(array_intersect([
'fixture',
'mysql',
'pgsql'], array_keys(
$options))) !== 1) {
11 fwrite(STDERR,
"Select one backend: --fixture=/path/to/isolated.sqlite, --mysql=lgv_tz_benchmark_NAME, or --pgsql=lgv_tz_benchmark_NAME\n");
15require_once
$source.
'/Sources/LGV_TZ_Lookup_Query.class.php';
16require_once dirname(__DIR__).
'/tests/support/SQLiteDatabase.php';
19 fwrite(STDERR,
"Build the isolated fixture first with --build.\n");
25 if (!preg_match(
'/^lgv_tz_benchmark_[a-zA-Z0-9_]+$/D',
$options[
$driver])) {
26 throw new InvalidArgumentException(
'Use a separate database named lgv_tz_benchmark_NAME.');
29 getenv(
'LGV_TZ_BENCH_USER') ?: (
$driver ===
'pgsql' ? (getenv(
'USER') ?: get_current_user()) :
'root'),
30 getenv(
'LGV_TZ_BENCH_PASSWORD') ?:
'',
$driver, getenv(
'LGV_TZ_BENCH_HOST') ?:
'localhost',
31 (
int)(getenv(
'LGV_TZ_BENCH_PORT') ?: (
$driver ===
'pgsql' ? 5432 : 3306)));
37 require_once
$source.
'/Sources/LGV_TZ_Lookup_Loader.class.php';
38 $stream = fopen(
$source.
'/combined-with-oceans.json',
'rb');
40 throw new RuntimeException(
'Boundary file unavailable.');
46 $database->pdo_instance->connection->beginTransaction();
49 $parser =
new JsonStreamingParser\Parser($stream, $listener);
52 $database->pdo_instance->connection->commit();
58 'mode' =>
'load',
'seconds' => (hrtime(
true) -
$start) / 1e9,
59 'peak_php_mib' => memory_get_peak_usage() / 1048576,
60 'polygons' =>
$database->pdo_instance->preparedStatement(
'SELECT COUNT(*) AS count FROM timezones', [],
true)[0][
'count'],
61 'polygon_bytes' =>
$database->pdo_instance->preparedStatement(
'SELECT SUM(LENGTH(polygon)) AS bytes FROM timezones', [],
true)[0][
'bytes'],
62 ], JSON_PRETTY_PRINT).
"\n";
66require dirname(__DIR__).
'/src/TestLocations.php';
69for ($i = 0; $i < (int)(
$options[
'random'] ?? 0); ++$i) {
70 $cases[] = [
'title' =>
'Random '.$i,
'params' => [
71 'lng' => mt_rand(-180000000, 180000000) / 1e6,
72 'lat' => mt_rand(-90000000, 90000000) / 1e6,
85for ($run = 0; $run < max(1, (
int)(
$options[
'runs'] ?? 3)); ++$run) {
86 foreach (
$cases as $caseIndex => $case) {
87 $longitude = $case[
'params'][
'lng'];
88 $latitude = $case[
'params'][
'lat'];
89 while ($longitude < -180) { $longitude += 360; }
90 while ($longitude > 180) { $longitude -= 360; }
91 while ($latitude < -90) { $latitude += 180; }
92 while ($latitude > 90) { $latitude -= 180; }
93 if (function_exists(
'memory_reset_peak_usage')) { memory_reset_peak_usage(); }
94 $memory = memory_get_usage();
95 $caseStart = hrtime(
true);
100 $result =
$lookup->get_tz($longitude, $latitude);
101 $elapsed = (hrtime(
true) - $caseStart) / 1e6;
108 $slowest[] = [
'title' => $case[
'title'],
'milliseconds' => $elapsed];
109 if (isset($case[
'result']) && $case[
'result'] !== $result) {
110 $failures[] = [
'title' => $case[
'title'],
'expected' => $case[
'result'],
'actual' => $result];
112 } elseif (
$results[$caseIndex] !== $result) {
113 throw new RuntimeException(
'Result changed between runs: '.$case[
'title']);
119usort(
$slowest,
static fn($a, $b) => $b[
'milliseconds'] <=> $a[
'milliseconds']);
121 file_put_contents(
$options[
'results'], json_encode(
$results, JSON_PRETTY_PRINT).
"\n");
124 'mode' =>
'query',
'backend' => isset(
$options[
'pgsql']) ?
'pgsql' : (isset(
$options[
'mysql']) ?
'mysql' :
'sqlite'),
125 'reconnect' => isset(
$options[
'reconnect']),
133], JSON_PRETTY_PRINT).
"\n";
135 fwrite(STDERR,
"Results differ from the supplied baseline.\n");
$test_locations_param_array
This file has a list of long/lat pairs, along with the expected results, when presented to the server...
if(isset($options['fixture']) &&!isset($options['build']) &&!is_file($options['fixture'])) $createDatabase
for($run=0; $run< max(1,(int)($options['runs'] ?? 3));++$run) $seconds