Без всяких причин, кроме забавы, я внедрил сегодня Trie. На данный момент он поддерживает add() и search(), remove() также должен быть реализован, но я думаю, что это довольно просто.Оптимизация реализации Trie
Это полностью функциональный, но заполнение Trie данными занимает немного слишком много для моего вкуса. Я использую этот список как источник данных: http://www.isc.ro/lists/twl06.zip (найден где-то еще на SO). Для загрузки требуется ~ 11 секунд. Моя первоначальная реализация заняла ~ 15 секунд, поэтому я уже дал ей хороший прирост производительности, но я все еще не удовлетворен :)
Мой вопрос: что еще может дать мне существенное повышение производительности? Я не связан этим дизайном, полный пересмотр является приемлемым.
class Trie
{
private $trie;
public function __construct(TrieNode $trie = null)
{
if($trie !== null) $this->trie = $trie;
else $this->trie = new TrieNode();
$this->counter = 0;
}
public function add($value, $val = null)
{
$str = '';
$trie_ref = $this->trie;
foreach(str_split($value) as $char)
{
$str .= $char;
$trie_ref = $trie_ref->addNode($str);
}
$trie_ref->value = $val;
return true;
}
public function search($value, $only_words = false)
{
if($value === '') return $this->trie;
$trie_ref = $this->trie;
$str = '';
foreach(str_split($value) as $char)
{
$str .= $char;
if($trie_ref = $trie_ref->getNode($str))
{
if($str === $value) return ($only_words ? $this->extractWords($trie_ref) : new self($trie_ref));
continue;
}
return false;
}
return false;
}
public function extractWords(TrieNode $trie)
{
$res = array();
foreach($trie->getChildren() as $child)
{
if($child->value !== null) $res[] = $child->value;
if($child->hasChildren()) $res = array_merge($res, $this->extractWords($child));
}
return $res;
}
}
class TrieNode
{
public $value;
protected $children = array();
public function addNode($index)
{
if(isset($this->children[$index])) return $this->children[$index];
return $this->children[$index] = new self();
}
public function getNode($index)
{
return (isset($this->children[$index]) ? $this->children[$index] : false);
}
public function getChildren()
{
return $this->children;
}
public function hasChildren()
{
return count($this->children)>0;
}
}
Вы уже профилированный код, используя [xhprof] (http://pecl.php.net/package/xhprof) или [Xdebug] (HTTP: // PECL .php.net/пакет/Xdebug)? – Charles
Я еще не знаю, хороший звонок. я буду завтра! –