We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 9207 ☆ A M B ☆
    • 2,475 Posts
    I have some formatting functions that I’ve developed that iterate over a series of database records. When this happens, I’m calling a function like this A LOT:

    public function parse($tpl, $record = array() ) {
    	$modChunk = $modx->newObject('modChunk');
    	$modChunk->setCacheable(false);
    	$modChunk->setContent($tpl);
    	return $modChunk->process( $record );
    }


    However, I’ve noticed that this function gets really slow when called repeatedly (sorry Jason, if you’re smacking your forehead right now).

    Is there any way that I can make this work faster for multiple iterations? I have a lot of different $tpl strings coming in, but there is a lot of repetition. I’ve been tinkering with this and I’ve only been able to make very small improvements in my page load times (one manager page is at 7+ seconds!!!). Any thoughts?

    Much appreciated!
      • 3749
      • 24,544 Posts
      If the tpl doesn’t change, you could just put it in a chunk and do something like this instead of the function call

      foreach($records as $record) {
          $output .= $modx->getChunk('TplChunk',$record->toArray());
      }


      Then you wouldn’t have the overhead of creating all those chunk objects that you don’t really need.

      It would be faster yet to just define the tpl string once and use str_replace on it each time through the loop.
        Did I help you? Buy me a beer
        Get my Book: MODX:The Official Guide
        MODX info for everyone: http://bobsguides.com/modx.html
        My MODX Extras
        Bob's Guides is now hosted at A2 MODX Hosting
        • 9207 ☆ A M B ☆
        • 2,475 Posts
        The $tpl changes each call... or almost every call. I have my own version of this function (a la Evo’s parse function) that’s based on str_replace, and it is MUCH faster. But I miss out on the opportunities of having output filters that way.
          • 3749
          • 24,544 Posts
          Quote from: Everett at Jan 22, 2011, 12:12 AM

          The $tpl changes each call... or almost every call. I have my own version of this function (a la Evo’s parse function) that’s based on str_replace, and it is MUCH faster. But I miss out on the opportunities of having output filters that way.

          If there’s a finite number of $tpls, you’d still be much better off putting them in an array and just selecting the appropriate one. You can still use toPlaceholders() and output modifiers, so they will be processed when the page is rendered.
            Did I help you? Buy me a beer
            Get my Book: MODX:The Official Guide
            MODX info for everyone: http://bobsguides.com/modx.html
            My MODX Extras
            Bob's Guides is now hosted at A2 MODX Hosting
            • 9207 ☆ A M B ☆
            • 2,475 Posts
            When you say "put them into an array", how exactly do you mean? Do you mean I should instantiate a finite # of modChunk objects? I’m not using the getChunk method because my formatting strings are not in the database, by the way.

            I could store the $tpl strings as hash keys... that would ensure that only unique $tpls would be stored. Something like:

            public $storage;
            
            public function parse($tpl, $record = array() ) {
            	if ( !is_object($this->storage[$tpl]) ) )
            	{
            		$this->storage[$tpl] = $modx->newObject('modChunk');
            		$this->storage[$tpl]->setContent($tpl);	
            	}
            	
            	return $this->storage[$tpl]->process( $record );
            }
            


            Is that crazy? It would allow me to enable caching...
              • 9207 ☆ A M B ☆
              • 2,475 Posts
              Ok, I tried the above (or something close to it), and it was only marginally faster... my page took 6.7 seconds to load. Without me re-usng the Chunks, it takes about 7.5 seconds to load. The str_replace version of the function causes this particular page to load in less than 0.2 seconds (!!).

              Were you thinking of a different approach, Bob?
                • 3749
                • 24,544 Posts
                I was thinking of something that didn’t need chunks at all if speed is really an issue.

                I was thinking of something like this if speed is an issue:

                <?php
                $tpls = array(
                
                   'tpl1'=> 'This is my first tpl [[+product]]',
                   'tpl2' => 'This is my second tpl [[+product]]',
                   'tpl3' => 'This is my third tpl [[+product]]',
                );
                
                foreach ($products as $product) {
                
                  $output .= str_replace('[[+product]]', $product->get('name'), $tpls['tpl1']);
                
                }


                You’d have to process any output modifiers yourself, but that would also speed thing up a lot.




                  Did I help you? Buy me a beer
                  Get my Book: MODX:The Official Guide
                  MODX info for everyone: http://bobsguides.com/modx.html
                  My MODX Extras
                  Bob's Guides is now hosted at A2 MODX Hosting
                  • 9207 ☆ A M B ☆
                  • 2,475 Posts
                  Yeah, I see where you’re going with that... hmm.... unfortunately my architecture is pretty built up at this point, so re-designing the structure of my objects/children/etc is probably not viable. Maybe I could get everything I need by doing the str_replace() and then doing a final pass through MODx’s process method -- any lingering unprocessed placeholders would be the ones that had output filters on them. The output filters aren’t a do or die necessity, they’re just really nice to have.

                  I’ll play around with it.
                    • 3749
                    • 24,544 Posts
                    I can see why you might want to do it the easy way. What I’m suggesting is basically how getResources and Wayfinder work, but if the hit in speed isn’t too bad, I usually use the built-in methods, although I’d probably use getChunk($tpl[$i], $properties), which seems easier to me, though I almost never use output modifiers. They’re painfully slow because before any work gets done, MODx has to parse not only the tags, but (separately) any modifiers, figure out what kind of modifier it is, look for chained modifiers, parse the conditions, etc. You can always do it faster in code because there’s no tag to parse you already know how the output should be modified.

                    Often, you can speed things up a lot just by pasting the modifier code into your snippet.
                      Did I help you? Buy me a beer
                      Get my Book: MODX:The Official Guide
                      MODX info for everyone: http://bobsguides.com/modx.html
                      My MODX Extras
                      Bob's Guides is now hosted at A2 MODX Hosting