Исходник теста:
<?
header
("Content-type: text/html; charset=utf-8");

class 
Cache {
    protected 
$module// Ссылка на модуль
    
protected $action// Название действия
    
    
public function setModule($module) {
        
$this->module $module;
    }
    
    public function 
setAction($action) {
        
$this->action $action;
    }
    
    public function 
getCacheFileName() {
        return 
"cache/".get_class($this)."_".$this->module->getName()."_".$this->action.".txt";
    }
    
    public function 
isCacheValid() {
        
clearstatcache();
        return 
file_exists($this->getCacheFileName()); // тупо проверяем, что файл существует
    
}
}

// Будем тестировать 3 способа кэширования:

class docCache extends Cache {
    
// 1. Кэшируем документ, загружаем/выгружаем данные через importNode
    
public function getNode($doc$module$action) {
        if (
$this->isCacheValid()) {
            
$cache_doc = new DOMDocument('1.0''utf-8');
            
$cache_doc->load($this->getCacheFileName());
            
$node $doc->importNode($cache_doc->documentElementtrue);
            return 
$node;
        }
    }
    
    public function 
saveNode($node) {
        
$doc = new DOMDocument('1.0''utf-8');
        
$cache_node $doc->importNode($nodetrue);
        
$doc->appendChild($cache_node);
        
$doc->save($this->getCacheFileName());
    }
}

class 
fragmentCache extends Cache {
    
// Кэшируем documentFragment
    // Вот тут не совсем все точно - кэш возвращает documentFragment вместо DOMElement. Ну да не важно :)
    
public function getNode($doc) {
        if (
$this->isCacheValid()) {
            
$f $doc->createDocumentFragment();
            
$xml_data file_get_contents($this->getCacheFileName());
            
$f->appendXML($xml_data);
            return 
$f;
        }
    }
    
    public function 
saveNode($node) {
        
$node_xml $node->ownerDocument->saveXML($node);
        
$file fopen($this->getCacheFileName(), 'w');
        
fputs($file$node_xml);
        
fclose($file);
    }
}

class 
structureCache extends Cache {
    
// Кэшируем собранную структуру через serialize();
    // При восстановлении перегоняем обратно в XML, используя соотв. метод модуля
    
public function getNode($doc) {
        if (
$this->isCacheValid()) {
            
$structure unserialize(file_get_contents($this->getCacheFileName()));
            
$node $doc->createElement($this->module->getName());
            
call_user_func(array($this->module$this->action."_structure2XML"), $structure$node);
            return 
$node;
        }
    }
    
    public function 
saveStructure($structure) {
        
$file fopen($this->getCacheFileName(), 'w');
        
fputs($fileserialize($structure));
        
fclose($file);
    }
}

class 
testModule {
    private 
$Cache false;
    
    
// Эти данные как-будто берутся из БД :)
    // Предполагается, что кэширование актуально
    
private $menu = array(
        
'about' => array(
            
'name' => 'О фирме',
            
'id' => 1,
            
'children' => array(
                
'policy' => array('name' => 'Политика компании''id' => 2),
                
'history' => array('name' => 'Наша история''id' => 3),
                
'staff' => array(
                    
'name' => 'Сотрудники',
                    
'id' => 4,
                    
'children' => array(
                        
'drivers' => array('name' => 'Водители''id' => 5),
                        
'managers' => array('name' => 'Менеджеры''id' => 6)
                    )
                )
            )
        ),
        
'service' => array(
            
'name' => 'Услуги',
            
'id' => 7,
            
'children' => array(
                
'rent' => array(
                    
'name' => 'Аренда автобуса',
                    
'id' => 8
                
),
                
'support' => array(
                    
'name' => 'Транспортная поддержка',
                    
'id' => 9
                
),
                
'meeting' => array(
                    
'name' => 'Встреча в аэропорту',
                    
'id' => 10
                
)
            )
        ),
        
'press' => array(
            
'name' => 'Пресс-центр',
            
'id' => 11,
            
'children' => array(
                
'news' => array('name' => 'Новости компании''id' => 12),
                
'industry-news' => array('name' => 'Новости индустрии''id' => 13)
            )
        ),
        
'buses' => array(
            
'name' => 'Наши автобусы',
            
'id' => 14,
            
'children' => array(
                
'lux' => array(
                    
'name' => 'Автобусы люкс-класса',
                    
'id' => 15,
                    
'children' => array(
                        
'mercedes-1' => array('name' => "Mercedes Benz 1"'id' => 16),
                        
'mercedes-2' => array('name' => "Mercedes Benz 2"'id' => 17),
                    )
                ),
                
'busines' => array(
                    
'name' => 'Автобусы бизнес-класса',
                    
'id' => 18,
                    
'children' => array(
                        
'man-1' => array('name' => "Man 1"'id' => 19),
                        
'man-2' => array('name' => "Man 2"'id' => 20),
                    )
                )
            )
        ),
        
'about1' => array(
            
'name' => 'О фирме',
            
'id' => 1,
            
'children' => array(
                
'policy' => array('name' => 'Политика компании''id' => 2),
                
'history' => array('name' => 'Наша история''id' => 3),
                
'staff' => array(
                    
'name' => 'Сотрудники',
                    
'id' => 4,
                    
'children' => array(
                        
'drivers' => array('name' => 'Водители''id' => 5),
                        
'managers' => array('name' => 'Менеджеры''id' => 6)
                    )
                )
            )
        ),
        
'about2' => array(
            
'name' => 'О фирме',
            
'id' => 1,
            
'children' => array(
                
'policy' => array('name' => 'Политика компании''id' => 2),
                
'history' => array('name' => 'Наша история''id' => 3),
                
'staff' => array(
                    
'name' => 'Сотрудники',
                    
'id' => 4,
                    
'children' => array(
                        
'drivers' => array('name' => 'Водители''id' => 5),
                        
'managers' => array('name' => 'Менеджеры''id' => 6)
                    )
                )
            )
        ),
        
'about3' => array(
            
'name' => 'О фирме',
            
'id' => 1,
            
'children' => array(
                
'policy' => array('name' => 'Политика компании''id' => 2),
                
'history' => array('name' => 'Наша история''id' => 3),
                
'staff' => array(
                    
'name' => 'Сотрудники',
                    
'id' => 4,
                    
'children' => array(
                        
'drivers' => array('name' => 'Водители''id' => 5),
                        
'managers' => array('name' => 'Менеджеры''id' => 6)
                    )
                )
            )
        ),
        
'about4' => array(
            
'name' => 'О фирме',
            
'id' => 1,
            
'children' => array(
                
'policy' => array('name' => 'Политика компании''id' => 2),
                
'history' => array('name' => 'Наша история''id' => 3),
                
'staff' => array(
                    
'name' => 'Сотрудники',
                    
'id' => 4,
                    
'children' => array(
                        
'drivers' => array('name' => 'Водители''id' => 5),
                        
'managers' => array('name' => 'Менеджеры''id' => 6)
                    )
                )
            )
        )
    );
    
    public function 
getName() {
        return 
"menu";
    }
    
    public function 
__construct() {
        
$this->doc = new DOMDocument('1.0''utf-8');
        
$this->root $this->doc->appendChild($this->doc->createElement('root'));
    }
    
    public function 
setCache($Cache) {
        if (
$Cache !== false) {
            
$this->Cache $Cache;
            
$this->Cache->setModule($this);
        }
    }
    
    public function 
show_menu_getStructure() {
        
// Вот тут должны были бы быть нагрузочные махинации с БД
        // Но нам лень их кодить.
        // Для наглядности посчитаем факториал 5000 - это где-то 0.002 сек., но не забываем про 1000 итераций!
        
$int 5000;
        for(
$f=2;$int-1>1;$f*=$int--);
        return 
$this->menu;
    }
    
    public function 
run($action) {
        if (
$this->Cache !== false) {
            
$this->Cache->setAction($action);
        }
        if (
$this->Cache !== false && ($node $this->Cache->getNode($this->doc$this$action))) {
            
// В нашем тесте кэш всегда возвращает нод
            // файлы кэша уже записаны и актуальность не проверяется
            
$this->root->appendChild($node);
        } else {
            
// А это как-будто проход без кэша (он уже сделан)
            
$node $this->root->appendChild($this->doc->createElement($action));
            
// Сначала вытаскиваем данные, собираем структуру массивов/объектов
            
$structure call_user_func(array($this$action.'_getStructure'));
            
// А потом перегоняем ее в DOM
            
call_user_func(array($this$action."_structure2XML"), $structure$node);
            
// И кэшируем
            
if ($this->Cache !== false) {
                if (
method_exists($this->Cache"saveNode")) { // для docCache и fragmentCache
                    
$this->Cache->saveNode($node);
                } else {
                    
$this->Cache->saveStructure($structure); // для structureCache
                
}
            }
        }
    }
    
    
// Эта штука рекурсивно превращает структуру массивов в XML
    // при кэшировании через structureCache вызывается каждый раз
    
function show_menu_structure2XML($arr$node) {
        
$doc $node->ownerDocument;
        foreach (
$arr as $code => $props) {
            
$item $node->appendChild($doc->createElement('item'));
            
$item->setAttribute('code'$code);
            
$item->setAttribute('name'$props['name']);
            
$item->setAttribute('id'$props['id']);
            if (isset(
$props['children'])) {
                
$this->show_menu_structure2XML($props['children'], $item);
            }
        }
    }
}

// Тест о 1000 прогонах

class Test {
    private 
$names = array();
    private 
$times = array();
    private 
$max_time 0;
    
    function 
run($Cache) {
        
$start microtime(true);
        for (
$i 0$i 1000$i++) {
            
$m = new testModule();
            
$m->setCache($Cache);
            
$m->run('show_menu');
        }
        
$elapsed microtime(true) - $start;
        
$test_name $Cache !== false get_class($Cache) : "noCache";
        if (
$elapsed $this->max_time) {
            
$this->max_time $elapsed;
        }
        
$this->names []= $test_name;
        
$this->times []= $elapsed;
    }
    
    public function 
drawChart() {
        
// Эта магическая штука юзает гуглевый API для создания графиков
        // См. http://code.google.com/apis/chart/
        
$proportion 80 $this->max_time;
        
$chart_url = array('names' => array(), 'data' => array());
        
        foreach (
$this->names as $key => $name) {
            
$time $this->times[$key];
            
$chart_url['names'] []= urlencode($name", ".(round($time 100) / 100)) . " s";
            
$chart_url['data'] []= round($time $proportion 10) / 10;
        }
        
        
$colors = array('009900''00cc66''ffcc00''cc0000');
        
$url "http://chart.apis.google.com/chart?cht=bvg&chd=t:".join("|"$chart_url['data']);
        
$url .= "&chs=300x100&chdl=".join("|"$chart_url['names'])."&chco=".join(","$colors);
        
?>
        <img src="<?=$url?>" /><br />
        <?
    
}
}

$max_time 0;
// Запускаем тесты
$Test = new Test();
$Test->run(new fragmentCache());
$Test->run(new docCache());
$Test->run(new structureCache());
$Test->run(false);
// Показываем табличку с результатом
$Test->drawChart();

// Показываем исходник :)
echo "<b>Исходник теста:</b><br />";
$file_source file_get_contents(__FILE__);
highlight_string($file_source);
// Типа все :)
?>