-
Notifications
You must be signed in to change notification settings - Fork 1
Performance overview
The JSON reader's performance is roughly 8-9 times that of the implementation in xp-framework/webservices, while it also uses less memory. On the other side, PHP's native json_decode()
function is 7-8 times faster (using current PHP 5.5). The figures for writing are 7-8 times better than xp-framework/webservices, and around twice as slow as PHP's native json_encode()
.
Given a test data size of 158791 bytes (inside a file on the local file system) and running parsing for 100 iterations, here is an overview of the results:
Implementation | Time | Per iteration | Memory usage / peak | Overhead |
---|---|---|---|---|
PHP Native | 0.239 seconds | 2.4 ms | 867.8 kB / 1616.4 kB | |
This (sequential) | 1.869 seconds | 18.7 ms | 857.3 kB / 893.6 kB | 16.3 ms |
This (serial) | 1.923 seconds | 19.2 ms | 848.1 kB / 1253.1 kB | 16.8 ms |
XP Webservices | 16.854 seconds | 168.5 ms | 1026.7 kB / 1510.7 kB | 166.1 ms |
The overhead for parsing a single 150 Kilobyte JSON file is around 17 milliseconds, which should be mostly acceptable.
Using the test data from above, written to a file on the local file system 100 times:
Implementation | Time | Per iteration | Memory usage / peak | Overhead |
---|---|---|---|---|
PHP Native | 0.390 seconds | 3.9 ms | 1324.4 kB / 1521.9 kB | |
This (sequential) | 0.709 seconds | 7.1 ms | 1384.7 kB / 1401.0 kB | 3.2 ms |
This (serial) | 0.705 seconds | 7.0 ms | 1353.9 kB / 1370.4 kB | 3.1 ms |
XP Webservices | 5.318 seconds | 53.2 ms | 1523.3 kB / 1544.6 kB | 49.3 ms |
The overhead is around 3 milliseconds, which is near to nothing.
The performance benefit vanishes when reading from a network socket and parsing the elements sequentially.
$c= new HttpConnection('https://api.github.com/orgs/xp-framework/repos');
$r= $c->get([], ['User-Agent' => 'xp-forge/json']);
// Native solution
$elements= json_decode(Streams::readAll($r->getInputStream()), true);
foreach ($elements as $element) {
}
// Solution using this implementation's sequential processing
$json= new StreamInput($r->getInputStream());
foreach ($json->elements() as $element) {
}
// Solution using this implementation's serial processing
$json= new StreamInput($r->getInputStream());
foreach ($json->read() as $element) {
}
// Solution using XP Webservices
$elements= (new JsonDecoder())->decodeFrom($r->getInputStream());
foreach ($elements as $element) {
}
The test data is the same size as above (158791 bytes).
Implementation | Time to 1st element | Time for all elements | Memory usage / peak |
---|---|---|---|
PHP Native | 0.718 seconds | 0.719 seconds | 1046.8 kB / 1752.6 kB |
This (sequential) | 0.143 seconds | 0.712 seconds | 1036.5 kB / 1078.8 kB |
This (serial) | 0.715 seconds | 0.717 seconds | 1027.0 kB / 1383.6 kB |
XP Webservices | 0.752 seconds | 0.752 seconds | 1210.5 kB / 1635.6 kB |
The memory saving when writing sequentially is most visible when working with streamed input data:
$c= new HttpConnection('http://real-chart.finance.yahoo.com/table.csv?s=UTDI.DE');
$r= $c->get([], ['User-Agent' => 'xp-forge/json']);
$csv= new CsvMapReader(new TextReader($r->getInputStream(), null), [], CsvFormat::$COMMAS);
$csv->setKeys($csv->getHeaders());
// Native solution
$struct= [];
while ($record= $csv->read()) {
$struct[]= $record;
}
FileUtil::setContents(new File('finance.json'), json_encode($struct, true));
// Solution using this implementation's sequential processing
$f= new FileOutput(new File('finance.json'));
with ($f->begin(Types::$ARRAY), function($stream) use($csv) {
while ($record= $csv->read()) {
$stream->element($record);
}
});
// Solution using this implementation's serial processing
$struct= [];
while ($record= $csv->read()) {
$struct[]= $record;
}
(new FileOutput(new File('finance.json')))->write($struct);
The test data downloaded is 169602 bytes, and results in a roughly 500 kB large JSON file.
Implementation | Time to process | Generated file size | Memory usage / peak |
---|---|---|---|
PHP Native | 0.947 seconds | 438121 bytes | 1259.1 kB / 5367.9 kB |
This (sequential) | 0.946 seconds | 516450 bytes | 1299.6 kB / 1421.5 kB |
This (serial) | 0.941 seconds | 516450 bytes | 1284.2 kB / 4729.2 kB |
XP Webservices | 1.129 seconds | 550021 bytes | 1459.7 kB / 5014.5 kB |