Reactive tree caching

Reactive tree caching

Building on the features of the first XTML template engine, we parse markup into a tree of objects instantiated from classes defining the behavior of the various elements. To render the document to XHTML, we recursively traverse the tree and each object is asked to generate a string representation of itself.

<xtm:google-map address="1501 Kincaid St, Eugene, OR 97403" height="300" width="400" />

For example is represented in PHP as something like this:

xtm_google_map Object
(
    [ns] => "xtm",
    [tag] => "google-map",
    [attribs] => Array
        (
            [address] => "1501 Kincaid St, Eugene, OR 97403",
            [height] => 300,
            [width] => 400
        )
    // etc...
)

And when the object renders itself, the script accesses the Google API to get the URL for the map image. This is outputted as an image tag in XHTML:

<img src="http://some.google.map?..." height="300px" width="400px" alt="1501 Kincaid St, Eugene, OR 97403" />

This works pretty well but until recently it has had some limitations. PHP’s serialize/unserialize functions get slow with very large strings so requests to heavy pages where complex document trees needed to load weren’t as snappy as we would like. To overcome this problem our new template objects store local caches that flush when new content is added to them. The effectiveness of these local caches is monitored and used to optimized the document trees by storing inactive segments in separate cache sets. These segments are only loaded back into the active document tree when an element they contain is accessed.

markup

Bearing in mind that the greatest strength of the system is the ability to efficiently output content that updates with varying frequency, I ran a quick performance comparison with some static markup from the Ticket Office home page. I used ab with 50 concurrent connections over 30 seconds against our development environment. The following results show a 53% improvement to requests per second over rebuilding the document every request and a 17% improvement over caching the full document tree:

No caching:

Time taken for tests:   30.34176 seconds
Complete requests:      4814
Failed requests:        0
Write errors:           0
Total transferred:      33388958 bytes
HTML transferred:       32218184 bytes
Requests per second:    160.28 [#/sec] (mean)
Time per request:       311.946 [ms] (mean)
Time per request:       6.239 [ms] (mean, across all concurrent requests)
Transfer rate:          1085.63 [Kbytes/sec] received

Simple caching:

Time taken for tests:   30.056 seconds
Complete requests:      6219
Failed requests:        0
Write errors:           0
Total transferred:      43165699 bytes
HTML transferred:       41649865 bytes
Requests per second:    207.30 [#/sec] (mean)
Time per request:       241.197 [ms] (mean)
Time per request:       4.824 [ms] (mean, across all concurrent requests)
Transfer rate:          1405.13 [Kbytes/sec] received

Optimized caching:

Time taken for tests:   30.14062 seconds
Complete requests:      7324
Failed requests:        0
Write errors:           0
Total transferred:      50898857 bytes
HTML transferred:       49111106 bytes
Requests per second:    244.02 [#/sec] (mean)
Time per request:       204.902 [ms] (mean)
Time per request:       4.098 [ms] (mean, across all concurrent requests)
Transfer rate:          1656.06 [Kbytes/sec] received

Tags: , , , , , , , , , ,

Paul Wells

I'm currently working as a web developer for EMU Marketing. I've been in and out of the office since 2004.

1 Comment Leave yours

  1. Shereen #

    Cool!

Leave a Reply