Могу поспорить, что многие ваши проблемы со скоростью связаны с тем, что вы выполняете итерацию и получаете несколько членов для каждой записи, каждый раз, когда поиск обновляется.
Я не уверен, как настроен ваш XML-файл (возможно, вы захотите опубликовать фрагмент, просто чтобы нам не приходилось догадываться по коду), но загружаю его в память и PHP-массивы при загрузке страницы (или даже когда сервер запускается, если вы можете сохранить его в кеше), тогда захват может быть лучшим решением.
Вы также упоминаете, что используете AJAX. Любой шанс, что вы можете отправить все это клиенту и позволить скрипту на его конце обрабатывать поиски (аналогично поиску в JavaScript в документации Doxygen). Это снимет нагрузку с вашего сервера и может оказаться более простым решением (вы просто отправите сценарий и файл XML поверх).
Редактировать: И если абсолютно ничего из этого не возможно, этот код должен быть на ощупь быстрее:
for($i=0; $i<($foodListXML->length); $i++)
{
$type=$foodListXML->item($i)->getElementsByTagName('type');
if ($type->item(0)->nodeType==1)
{
// move these in here, so if the nodeType is wrong, don't bother looking them up
$foodnote=$foodListXML->item($i)->getElementsByTagName('foodnote');
$style=$foodListXML->item($i)->getElementsByTagName('style');
//find a link matching the search text
if (stristr($type->item(0)->childNodes->item(0)->nodeValue,$q))
{
$currentFoodName = $type->item(0)->childNodes->item(0)->nodeValue;
$currentFoodStyle = $style->item(0)->childNodes->item(0)->nodeValue;
$currentFoodNote = $foodnote->item(0)->childNodes->item(0)->nodeValue;
if ($hint=="")
{
$hint= $currentFoodName . " , " . $currentFoodNote . " , <b>" . $currentFoodStyle. "</b>" . "<br>" ;
} else {
$hint=$hint . $currentFoodName . " , " . $currentFoodNote . " , <b>" . $currentFoodStyle. "</b>" . "<br>" ;
}
}
}
}