Skip to content

Performance overview

thekid edited this page Sep 14, 2014 · 1 revision

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().

Reading

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.

Writing

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.

Network I/O

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

Sequential writing

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
Clone this wiki locally