php5 DOM getElement versus XPATH

En una de las tantas pruebas que le he realizado a mi toolkit de manejo de XML (tomates xml) he llegado a la pregunta que muchos se habrán hecho; en vista que jquery usa XPATH para hacer busquedas y realmente es mucho más rapido que otros toolkits en javascript; ¿sucederá lo mismo con php5?, ¿quien será más rápido?, ¿DOM getElement o XPATH?; bueno, vamos a comprobarlo.

La librería:

una librería DOM XML que posee un método extendido llamado get; su código:

//retorna un nodo especificado como nodo dom:
public function get($name) {
if ($name) {
$node = $this->getElementById($name);
if ($node) {
return $node;
} else {
throw new splib_exception("Debe especificar un nombre de nodo valido: {$name} no existe");
return false;
}
} else {
throw new splib_exception("debe especificar un nombre de nodo valido");
}
}

He agregado luego una función para buscar usando xpath:

//un get basado en xpath
public function getXpath($name) {
if ($name) {
$node = $this->_xpath->query("//*[@id='{$name}']");
if ($node) {
return $node;
} else {
throw new splib_exception("Debe especificar un nombre de nodo valido: {$name} no existe");
return false;
}
} else {
throw new splib_exception("debe especificar un nombre de nodo valido");
}
}

Para la función anterior debemos primero crear un objeto xpath:

//gestor de busquedas xpath
$this->_xpath = new DOMXPath($this);

Y dos funciones más que buscan etiquetas (tags) y no id:

query usa xpath->query

//hace una consulta xpath sobre el arbol actual:
public function query($q, $item = null) {
if ($q) {
$node = $this->_xpath->query($q);
}
if ($node){
if ($item) {
return $node->item($item);
} elseif ($node->length == 1) {
#como no hay 2 items, devuelvo el unico que existe
return $node->item(0);
} else {
#retorno una serie de items, como elementos dom_element
return $node;
}
} else {
return false;
}
}

y element usa getElementsByTagName

#retorna uno o una coleccion de elementos xml en forma de nodos DOM
public function element($name, $item = null) {
if ($name) {
$node = $this->getElementsByTagName($name);
if ($node){
if ($item) {
return $node->item($item);
} elseif ($node->length == 1) {
#como no hay 2 items, devuelvo el unico que existe
return $node->item(0);
} else {
#retorno una serie de items, como elementos dom_element
return $node;
}
} else {
return false;
}
} else {
throw new splib_exception('debe especificar un nombre de elemento');
}
}

Las pruebas:

Ejecutamos ambas funciones sobre un documento HTML cualquiera 10 mil veces:

$this->_html = new splib_dom();
$this->_html->load('pruebas/index.html');
splib_config::start_clock();
for($i=1;$i _html->get('main');
}
echo 'busqueda basada en getElementById: ' . splib_config::time_elapsed() . '
'; splib_config::start_clock(); for($i=1;$i _html->getXpath('main'); } echo 'busqueda basada en xpath: ' . splib_config::time_elapsed() . '
'; splib_config::start_clock(); for($i=1;$i _html->element('title'); } echo 'busqueda basada en getElementsByTagName: ' . splib_config::time_elapsed() . '
'; splib_config::start_clock(); for($i=1;$i _html->query('html/head/title'); } echo 'busqueda basada en query XPATH /html/head/title: ' . splib_config::time_elapsed() . '
';

La idea es que cualquiera puede sustituir splib_dom por new DOMDocument (splib_dom es una extensión directa de DOMDocument con más funciones); y splib_config es una clase que uso para obtener informacion (en este caso; lleva un contador usando la funcion microtime()).

Los resultados son interesantes:

busqueda basada en getElementById: 0.06926 s
busqueda basada en xpath: 0.15377 s
busqueda basada en getElementsByTagName: 0.12167 s
busqueda basada en query XPATH /html/head/title: 0.15929 s

Como veremos; las búsquedas basadas en getElementById son muchisimo más rápidas que su contraparte búsqueda via xpath; igualmente las búsquedas via getElementsByTagName son más rápidas que la búsqueda via nodos xpath (aunque en este caso; es más util buscar usando paths de XPATH cuando se desea un mayor control sobre las busquedas).

Bueno, para todo el que tenía la duda, he aqui la respuesta.

Acerca de phenobarbital

http://about.me/phenobarbital

Publicado el 5 noviembre 2007 en PHP, PlanetaLinux, Programacion. Añade a favoritos el enlace permanente. Deja un comentario.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: