Skip to content

Commit

Permalink
benchmarks
Browse files Browse the repository at this point in the history
  • Loading branch information
jphenow committed Mar 29, 2022
1 parent 25c11d5 commit bd05f1d
Show file tree
Hide file tree
Showing 17 changed files with 816 additions and 0 deletions.
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ Use Rust to provide fast TOML parsing to PHP.

This is somewhat experimental at the moment, but happy to help anyone take it to the next stage.

This was written after leaving a company that used PHP and I had some performance issues in particular cases.
I will not be using PHP professionally for the foreseeable future, so if you'd like to take this project and turn it into a published library please do so.

## Building, extending PHP

```sh
Expand All @@ -20,3 +23,29 @@ $> php -dextension=path-to-project/target/debug/libtomlrs_php.dylib <your php fi
$parsed = parse_toml(__DIR__ . "/test.toml");
var_dump($parsed); // key-value array of TOML values
```

## Benchmark

Run on my Macbook Pro:

```
Processor Name: 8-Core Intel Core i9
Processor Speed: 2.4 GHz
Number of Processors: 1
Total Number of Cores: 8
L2 Cache (per Core): 256 KB
L3 Cache: 16 MB
Hyper-Threading Technology: Enabled
Memory: 64 GB
```

Running each parser of [an example toml file](./benchmarks/test.toml) 1000 times and collecting the average time to parse:

| Library | Time (average in milliseconds) |
| ------ | -------- |
| `jamesmoss/toml` | 0.381ms |
| `leonelquinteros/php-toml` | 0.847ms |
| `yosymfony/toml` | 2.298ms |
| `tomlrs-php` | 0.129ms |

For more information, see the [benchmarks dir](./benchmarks/).
33 changes: 33 additions & 0 deletions benchmarks/bench.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/usr/bin/env bash

set -euo pipefail

ONLY="${ONLY:-}"

benches=(
"jamesmoss-toml"
"leonelquinteros-php-toml"
"yosymfony-toml"
"tomlrs-php"
)

export TIMES=1000
benchDir="$PWD"

for benchProject in "${benches[@]}"; do
# TODO: output device info

if [ "$ONLY" != "" ] && [ "$ONLY" != "$benchProject" ]; then
continue
fi

cd $benchProject > /dev/null

if [ "$benchProject" == "tomlrs-php" ]; then
echo "$benchProject: $(php -dextension=/Users/jphenow/Code/tomlrs-php/target/release/libtomlrs_php.dylib index.php)ms"
else
echo "$benchProject: $(php index.php)ms"
fi
cd .. > /dev/null
done

2 changes: 2 additions & 0 deletions benchmarks/jamesmoss-toml/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
vendor/

5 changes: 5 additions & 0 deletions benchmarks/jamesmoss-toml/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"require": {
"jamesmoss/toml": "^1.1"
}
}
66 changes: 66 additions & 0 deletions benchmarks/jamesmoss-toml/composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

55 changes: 55 additions & 0 deletions benchmarks/jamesmoss-toml/index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

require __DIR__ . "/vendor/autoload.php";

use Toml\Parser;

$verbose = getenv("VERBOSE") == "1";
$times = intval(getenv("TIMES"));
$expected = [
"foo" => "bar",
"section" => [
"one" => 2,
"boolean" => true,
"subsection" => [
"an-array" => [
"of",
"values"
]
]
]
];

$file = __DIR__ . "/../test.toml";
$toml = [];
$startTime = 0;
$endTime = 0;
$took = 0;
$totalTime = 0;

for ($i = 0; $i < $times; $i++) {
$startTime = microtime(true);
$toml = Parser::fromFile($file);
$endTime = microtime(true);
$took = ($endTime - $startTime)*1000;
$totalTime += $took;
}
// $toml === $expected ? exit(0) : exit(1);
$matched = $toml === $expected;

if ($verbose) {
printf($matched ? "Values matched\n" : "Values did not match\n");
if (!$matched) {
printf("Expected: ");
var_dump($expected);
printf("Got: ");
var_dump($toml);
}

printf("Times: %s\n", $times);
printf("Last parsing took %sms\n", $took);
printf("Total parsing took %sms\n", $totalTime);
printf("Average parsing took %sms\n", $totalTime/$times);
} else {
printf($totalTime/$times);
}
2 changes: 2 additions & 0 deletions benchmarks/leonelquinteros-php-toml/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
vendor/

5 changes: 5 additions & 0 deletions benchmarks/leonelquinteros-php-toml/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"require": {
"leonelquinteros/php-toml": "^1.1"
}
}
72 changes: 72 additions & 0 deletions benchmarks/leonelquinteros-php-toml/composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

54 changes: 54 additions & 0 deletions benchmarks/leonelquinteros-php-toml/index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

require __DIR__ . "/vendor/autoload.php";

$verbose = getenv("VERBOSE") == "1";
$times = intval(getenv("TIMES"));
$expected = [
"foo" => "bar",
"section" => [
"one" => 2,
"boolean" => true,
"subsection" => [
"an-array" => [
"of",
"values"
]
]
]
];

$file = __DIR__ . "/../test.toml";
$toml = [];
$startTime = 0;
$endTime = 0;
$took = 0;
$totalTime = 0;

for ($i = 0; $i < $times; $i++) {
$startTime = microtime(true);
$toml = Toml::parseFile($file);
$endTime = microtime(true);
$took = ($endTime - $startTime)*1000;
$totalTime += $took;
}
// $toml === $expected ? exit(0) : exit(1);
$matched = $toml === $expected;

if ($verbose) {
printf($matched ? "Values matched\n" : "Values did not match\n");
if (!$matched) {
printf("Expected: ");
var_dump($expected);
printf("Got: ");
var_dump($toml);
}

printf("Times: %s\n", $times);
printf("Last parsing took %sms\n", $took);
printf("Total parsing took %sms\n", $totalTime);
printf("Average parsing took %sms\n", $totalTime/$times);
} else {
printf($totalTime/$times);
}

Loading

0 comments on commit bd05f1d

Please sign in to comment.