mirror of
https://github.com/twigphp/Twig.git
synced 2026-09-15 11:56:50 +00:00
made a huge optimization for loops (up to 50% faster now)
git-svn-id: http://svn.twig-project.org/trunk@117 93ef8e89-cb99-4229-a87c-7fa0fa45744b
This commit is contained in:
@@ -58,10 +58,13 @@ class Twig_Node_For extends Twig_Node implements Twig_NodeListInterface
|
||||
$compiler->write("\$context['_iterated'] = false;\n");
|
||||
}
|
||||
|
||||
$var = rand(1, 999999);
|
||||
$compiler
|
||||
->write('foreach (twig_iterate($context, ')
|
||||
->write("\$seq$var = twig_iterator_to_array(")
|
||||
->subcompile($this->seq)
|
||||
->raw(") as \$iterator)\n")
|
||||
->raw(");\n")
|
||||
->write("\$context['loop']['length'] = count(\$seq$var);\n")
|
||||
->write("for (\$i$var = 0; \$i$var < \$context['loop']['length']; \$i$var++)\n")
|
||||
->write("{\n")
|
||||
->indent()
|
||||
;
|
||||
@@ -71,7 +74,7 @@ class Twig_Node_For extends Twig_Node implements Twig_NodeListInterface
|
||||
$compiler->write("\$context['_iterated'] = true;\n");
|
||||
}
|
||||
|
||||
$compiler->write('twig_set_loop_context($context, $iterator, ');
|
||||
$compiler->write("twig_set_loop_context(\$context, \$seq$var, \$i$var, ");
|
||||
|
||||
if ($this->isMultitarget)
|
||||
{
|
||||
|
||||
+13
-68
@@ -4,103 +4,48 @@
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
class Twig_LoopContextIterator implements Iterator
|
||||
function twig_iterator_to_array($seq)
|
||||
{
|
||||
public $context;
|
||||
public $seq;
|
||||
public $idx;
|
||||
public $length;
|
||||
public $parent;
|
||||
|
||||
public function __construct(&$context, $seq, $parent)
|
||||
{
|
||||
$this->context = $context;
|
||||
$this->seq = $seq;
|
||||
$this->length = count($this->seq);
|
||||
$this->parent = $parent;
|
||||
}
|
||||
|
||||
public function rewind()
|
||||
{
|
||||
$this->idx = 0;
|
||||
}
|
||||
|
||||
public function key()
|
||||
{
|
||||
}
|
||||
|
||||
public function valid()
|
||||
{
|
||||
return $this->idx < $this->length;
|
||||
}
|
||||
|
||||
public function next()
|
||||
{
|
||||
$this->idx++;
|
||||
}
|
||||
|
||||
public function current()
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
function twig_iterate(&$context, $seq)
|
||||
{
|
||||
$parent = isset($context['loop']) ? $context['loop'] : null;
|
||||
|
||||
// convert the sequence to an array of values
|
||||
// we convert Iterators as an array
|
||||
// as our iterator access the sequence as an array
|
||||
if (is_array($seq))
|
||||
{
|
||||
$array = array_values($seq);
|
||||
return array_values($seq);
|
||||
}
|
||||
elseif (is_object($seq) && $seq instanceof Iterator)
|
||||
{
|
||||
$array = iterator_to_array($seq, false);
|
||||
return iterator_to_array($seq, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
$array = array();
|
||||
return array();
|
||||
}
|
||||
|
||||
$context['loop'] = array('parent' => $parent);
|
||||
|
||||
return new Twig_LoopContextIterator($context, $array, $parent);
|
||||
}
|
||||
|
||||
function twig_set_loop_context(&$context, $iterator, $target)
|
||||
function twig_set_loop_context(&$context, $seq, $idx, $target)
|
||||
{
|
||||
$idx = $iterator->idx;
|
||||
|
||||
if (is_array($target))
|
||||
{
|
||||
foreach ($target as $key => $value)
|
||||
{
|
||||
$context[$value] = $iterator->seq[$idx][$key];
|
||||
}
|
||||
$context[$target[0]] = $seq[$idx][0];
|
||||
$context[$target[1]] = $seq[$idx][1];
|
||||
}
|
||||
else
|
||||
{
|
||||
$context[$target] = $iterator->seq[$idx];
|
||||
$context[$target] = $seq[$idx];
|
||||
}
|
||||
|
||||
$context['loop'] = array(
|
||||
'parent' => $iterator->parent,
|
||||
'length' => $iterator->length,
|
||||
'parent' => $context['_parent'],
|
||||
'length' => $context['loop']['length'],
|
||||
'index0' => $idx,
|
||||
'index' => $idx + 1,
|
||||
'revindex0' => $iterator->length - $idx - 1,
|
||||
'revindex' => $iterator->length - $idx,
|
||||
'revindex0' => $context['loop']['length'] - $idx - 1,
|
||||
'revindex' => $context['loop']['length'] - $idx,
|
||||
'first' => $idx == 0,
|
||||
'last' => $idx + 1 == $iterator->length,
|
||||
'last' => $idx + 1 == $context['loop']['length'],
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user