We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 22295
    • 153 Posts
    (to make a long story short)
    add a [[+validTag]] many times and time the php execution.
    then change them all to [[+NOTvalidTag]] - the execution time will be 150% longer (!!).

    why?
    any tip to get around it?
      • 22303 MODX Staff
      • 10,725 Posts
      Quote from: oori at Apr 01, 2010, 06:43 PM

      (to make a long story short)
      add a [[+validTag]] many times and time the php execution.
      then change them all to [[+NOTvalidTag]] - the execution time will be 150% longer (!!).

      why?
      Because unprocessed tags are preserved until the final pass, so that means attempts are made to process them on every pass. Though 150% seems a bit excessive; I’ll do some profiling and see what I can discover.

      Quote from: oori at Apr 01, 2010, 06:43 PM

      any tip to get around it?
      Don’t place invalid tags in your content, or at least have the insight to make them all non-cacheable. tongue

      But seriously, I’ll look into the performance and see what we can do. There is likely room for optimization in many areas still, and now that we are in RC mode, we can focus on bug fixes, usability improvements, and optimizations.
        • 22295
        • 153 Posts
        so that means attempts are made to process them on every pass
        practically - this mean the default 10 times?

        Don’t place invalid tags in your content, or at least have the insight to make them all non-cacheable.


        I’ll be concrete with one example:
        ’members’ are extended modUser with a bunch of tables and relationships..
        Member can have multiple professions, lets say up to three, for the example (musician, programmer and street-cleaner - a perfectly normal situation in our days...). ofource, he also just be a ’CEO’...

        ok, seriously - the listMembers snippet gets all this data (xpdo) then creates chronological-placeholders (attached below) and then parsing via getChunk(’memberTpl’).
        ’memberTpl’ must contain tag placeholder for all three potential professions, if they exist or not.

        So, as you suggest - to resolve the performance issue for that situation, I must create empty placeholders for the non-existing professions..
        mm... not so elegant (although seems like the simplest way). can I somehow force single-pass over tags parsing?




        In general - I’m now doing many performance enhancement on this application (revo based social-network), and I see my biggest hogs are always placeholders and filters related (:userinfo, :memberinfo, :resourceinfo -- all i’m getting rid of now..)
        As the application is still growing (design and functionality-wise), it’s a game between better performance and simpler changes. seems I’ll play on the game..
        I "allowed" myself to use setPlaceholders a lot (much more then precise getChunk(’tpl’,array(specific)), as I saw you guys fill up the placeholders too. There’s undoubtedly a place for performance improvements on that part.

        or at least have the insight to make them all non-cacheable
        What do you mean?
        Something like this would still not resolve it.
        Actually - modx tag parsing has nothing to do with the [[if, it’ll parse everything in any case...

        		[[!if? &subject=`[[+[[+userId]].MemberSkillGroups.3.skillId]]` &operator=`notempty` 
        			&then=`
        				<img class="icon tiny" src="[[++base_url]]assets/members/skillgroups/[[+[[+userId]].MemberSkillGroups.3.skillId]].png" alt="icon "/>
        				<h2>[[+[[+userId]].MemberSkillGroups.3.Professions]]</h2>
        			` 
        		]]




        ATTACHMENT:
        /*  same as toPlaceholders, but naming in 1.2.3.4.. order, and not PK-based (as toPlaceholderS)  */
        function chronologicalPlaceholder($parentObj,$alias,$prefix) {
        	global $modx;
        	if (!isset($prefix)) {$prefix = $alias;}	// default to use alias as placeholder prefix
        	$childs = $parentObj->getMany($alias);			// get all children
        	sort($childs);									// change array's keys to 0,1,2,etc...
        	array_unshift($childs,array());   				// add empty one, simply so the numbering will start from 1 and not 0
        	$modx->toPlaceholders($childs,$prefix,".");	// generate modx placeholders for templates
        	return $childs;								// return the array, needed for recursive placeholder (grandchildren relationship or more)
        }
          • 22303 MODX Staff
          • 10,725 Posts
          Quote from: oori at Apr 01, 2010, 07:35 PM

          so that means attempts are made to process them on every pass
          practically - this mean the default 10 times?
          No; totally depends on where it appears. Could be a lot more than that if you are using them in chunks within loops. Remember, all parsing in Revolution is true source order and fully recursive, as opposed to Evo.

          Quote from: oori at Apr 01, 2010, 07:35 PM

          I "allowed" myself to use setPlaceholders a lot (much more then precise getChunk(’tpl’,array(specific)), as I saw you guys fill up the placeholders too. There’s undoubtedly a place for performance improvements on that part.
          Remember that passing properties to elements creates placeholders only within the scope of that element, and they are removed once the element is processed. This is totally different than setting placeholders for the entirety of the request.

          Quote from: oori at Apr 01, 2010, 07:35 PM

          or at least have the insight to make them all non-cacheable
          What do you mean?
          I mean, non-cacheable tags are ignored until the final two sets of passes (unless they are nested within a cacheable tag string itself), including any tags embedded within the non-cacheable tag. Of course, if you can cache them, then the overhead of the processing only occurs once.
            • 22295
            • 153 Posts
            Thanks for your replies.

            Remember that passing properties to elements creates placeholders only within the scope of that element, and they are removed once the element is processed. This is totally different than setting placeholders for the entirety of the request.

            This is clear. I am already moving most code to scope-specific (for performance reasons. the original question regarding non-valid tags, it does not resolve as they would still be parsed on later passes).
            One general questions on this topic: the down-side of many placeholders (non-scoped) is mainly memory usage? or would it also affect php processing time.


            Of course, if you can cache them, then the overhead of the processing only occurs once.
            no way for $modx->getChunk to use cache, or am i wrong? as far as i know, I can cache the snippet’s final output (element cache) or implement my own cacheManager, correct?


            Thanks again.
              • 22303 MODX Staff
              • 10,725 Posts
              Quote from: oori at Apr 01, 2010, 10:11 PM

              One general questions on this topic: the down-side of many placeholders (non-scoped) is mainly memory usage? or would it also affect php processing time.
              There is always a correlation. More memory usage will mean more processing time in almost every case.

              Quote from: oori at Apr 01, 2010, 10:11 PM

              Of course, if you can cache them, then the overhead of the processing only occurs once.
              no way for $modx->getChunk to use cache, or am i wrong? as far as i know, I can cache the snippet’s final output (element cache) or implement my own cacheManager, correct?
              Are you talking about caching the source content of the Chunk or the processed output of the Chunk? Big difference.
                • 22295
                • 153 Posts
                Are you talking about caching the source content of the Chunk or the processed output of the Chunk? Big difference.

                Please elaborate and correct me if i got it right:
                For caching the source content of the chunk - we’re talking about using cacheManager and/or xpdo’s cache (or another custom cache, external to modx).

                For the processed Chunk - getChunk() will not be cached (same as ->runSnippet), unless it resided in a cached snippet call. the direct result of a getChunk() will not be specifically cached with Element Caching, but it’s processed output will be part of the snippet’s cache itself.
                When getChunk (or getSnippet) is called from an uncached snippet call, cacheManager would be needed to handle specific caching for these calls.

                And in general, Modx cache is not timebased or change-based, such as xpdo’s sql caching (ie. cache_db).

                http://svn.modxcms.com/docs/display/revolution/Caching

                Cache for the processed Chunk interests me more then caching the source of the content, as the second is quite robust (my performance issues are presentation related, not query related).
                http://modxcms.com/forums/index.php/topic,43305.msg259521.html#msg259521

                Following this list, I know you are "the man of php performance" smiley
                Thanks again for your replies.