Saturday 24 March 2007 9:52:53 am - 7 replies
I have a page with a Google Map and I want to create content for the script taking it from 2 classes named "Place" and "Insertion". Each insertion is related to a Place and has an enum attribute containing the kind of a place. For each place I have to count the number of times a particular enumvalue appears in all insertions related to it. Then I'd like to print only the three best kinds in witch each palce has been categorized.
This code is very slow, but I don't know how to speed it up, can you help me, please?
{def $places=fetch('content','list',hash(parent_node_id,59))}
{foreach $places as $p1}
{def $content=concat('<a href=',
$p1.path_identification_string|ezurl(no),
'><b>', $p1.object.data_map.name.data_text,
'</b></a> - ', $p1.creator.name,'<br />') }
{set $content=concat($content,'<br /><b>Tipologia:</b>')}
{def $kind_elements=array()}
{def $kind_elements_count=array()}
{def $insertions=fetch('content','list',
hash(parent_node_id,$p1.node_id,
order_by,array('published',true()),class_filter_type,
"include", class_filter_array, array(17)) ) }
{foreach $insertions[0].object.data_map.kind.value.enum_list as $enum_element}
{set $kind_elements=$kind_elements|append($enum_element.enumelement)}
{set $kind_elements_count=$kind_elements_count|append(0)}
{/foreach}
{foreach $insertions as $insertion}
{for 0 to sum(count($kind_elements),-1) as $i}
{if eq($insertion.object.data_map.kind.value.enumobject_list[0].enumelement,
$kind_elements[$i]) }
{def $e=$kind_elements_count[$i]}
{set $e=sum($e,1)}
{set $kind_elements_count=$kind_elements_count|remove($i,1)}
{set $kind_elements_count=$kind_elements_count|insert($i,$e)}
{undef $e}
{/if}
{/for}
{/foreach}
{if ge(count($kind_elements),2)}
{def $swapped=false()}
{do}
{set $swapped=false()}
{for 0 to sum(count($kind_elements),-2) as $i }
{if lt($kind_elements_count[$i],$kind_elements_count[sum($i,1)]) }
{def $tmp1=$kind_elements_count[$i]}
{set $kind_elements_count=$kind_elements_count|remove($i,1)}
{set $kind_elements_count=
$kind_elements_count|insert($i,$kind_elements_count[$i])}
{set $kind_elements_count=$kind_elements_count|remove(sum($i,1),1)}
{set $kind_elements_count=
$kind_elements_count|insert(sum($i,1),$tmp1)}
{undef $tmp1}
{def $tmp1=$kind_elements[$i]}
{set $kind_elements=$kind_elements|remove($i,1)}
{set $kind_elements=$kind_elements|insert($i,$kind_elements[$i])}
{set $kind_elements=$kind_elements|remove(sum($i,1),1)}
{set $kind_elements=$kind_elements|insert(sum($i,1),$tmp1)}
{undef $tmp1}
{set $swapped=true()}
{/if}
{/for}
{/do while $swapped }
{undef $swapped}
{/if}
{for 0 to min(2,sum(count($kind_elements),-1)) as $i}
{if gt($kind_elements_count[$i],0)}
{set $content=concat($content,' ',$kind_elements[$i],
' (',$kind_elements_count[$i],') ')}
{/if}
{/for}
{*then I pass the $content variable to the function addMarker of the Google Maps*}
Modified on Saturday 24 March 2007 10:03:18 am by Matteo Tomasini
Saturday 24 March 2007 10:32:01 am
@Matteo,
While I am impressed with your first post being so very detailed,
I fear the first thought when I glanced at your first post was ....
Most of this code belongs in php instead of tpl.
In moving the logic (up the chain-o-command) to php (I think) you will the gain motivating performance improvements you seek.
You might want to take a look at using the Wrap Operator extension which can provide a simple flexible way to write a php code which can return results inside of a template using a custom template operator. http://ezpedia.org/wiki/en/ez/wrap_operator
<i>//kracker
Audio Book - Noam Chomsky : Failed States Unabridged</i>
Modified on Saturday 24 March 2007 10:33:22 am by kracker
Monday 26 March 2007 10:44:19 am
This is the code in the template
{def $kinds=array('Bene culturale','Luogo rupestre','Paesaggio/Attrazione naturale','Flora/Fauna')}
{def $places=fetch('content','list',hash(parent_node_id,59))}
{foreach $places as $place}
{def $content=concat('<a href=',$place.path_identification_string|ezurl(no),' ><b>',$place.object.data_map.name.data_text,'</b></a> - ',$place.creator.name,'<br />')}
{def $insertions=fetch('content','list',hash(parent_node_id,$place.node_id,
order_by,array('published',true()),class_filter_type, "include", class_filter_array, array(17)) ) }
{set $content=concat($content,'<br /><b>Tipologia:</b>',wrap_user_func('generateMarkerContent', array($kinds,2,$insertions)))}
{*then I pass the $content variable to the function addMarker of the Google Maps*}
The values passed to the 'generateMarkerContent' function represent the list of kinds, the array position of the Selection attribute 'kind' and the list of insertions associated to a place.
This is the 'generateMarkerContent' function
function generateMarkerContent($list,$type,$insertions)
{
$count=array();
$allKinds=array();
foreach($insertions as $insertion) {
end($insertion->ContentObject->ContentObjectAttributes);
$curr=current($insertion->ContentObject->ContentObjectAttributes);
array_push($allKinds,$list[$curr['eng-GB'][$type]->DataText]);
}
$count=array_count_values($allKinds);
arsort($count);
$str='';
for ($i=0; $i<3; $i++)
{
$curr=each($count);
if (isset($curr['key']))
$str=$str . ' ' . $curr['key'] . '(' . $curr['value'] . ')';
}
if (count($count)>3)
$str=$str . ' ...'
return ($str);
}
?>
it returns a string containing the 3 most rated kinds
Tuesday 27 March 2007 8:13:12 am
@Xavier Dutoit
Before the modification the template processing time was about 8 seconds, now is less than a second. During this time the CPU works at 100% (I have an AMD Athlon 64 3500+). The page has 5 places and about 20 Insertions.
Now I have inserted 9 places with about 50 Insertions and the template time is about 1.8sec, always with the CPU at 100%. I am quite worried about that, with about 100 places and 1000-1500 Insertions what will be the load page time? Have you got some more ideas to improve speed of my page?
Thanks
Tuesday 27 March 2007 11:47:29 am
Hi,
Assuming places and so on aren't going to change that often, use cache-block around them (with the right keys and update only when a new place is published, no time out). That's still as slow the first time, but much quicker the other times.
Have a look at the documentation.
X+
You must be logged in to post messages in this topic!