We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
  • I'm also watching this discussion.
    It might be my lucky moment, because I tried to sum up the chunk methods several days ago to be used regularly for add-ons.
    https://github.com/goldsky/modx-chunk-methods

    And it includes @BINDINGs detection.

    Besides of the slow performance of the direct getChunk() method, do the other way arounds have some kind of policies attached or inherited?
      Rico
      Genius is one percent inspiration and ninety-nine percent perspiration. Thomas A. Edison
      MODx is great, but knowing how to use it well makes it perfect!

      www.virtudraft.com

      Security, security, security! | Indonesian MODx Forum | MODx Revo's cheatsheets | MODx Evo's cheatsheets

      Author of Easy 2 Gallery 1.4.x, PHPTidy, spieFeed, FileDownload R, Upload To Users CMP, Inherit Template TV, LexRating, ExerPlan, Lingua, virtuNewsletter, Grid Class Key, SmartTag, prevNext

      Maintainter/contributor of Babel

      Because it's hard to follow all topics on the forum, PING ME ON TWITTER @_goldsky if you need my help.
    • Quote from: goldsky at Feb 28, 2012, 04:33 PM
      Besides of the slow performance of the direct getChunk() method, do the other way arounds have some kind of policies attached or inherited?
      Yes, the sourceCache contains the policies for the element, so once loaded, from database, previous call to it in same request, or from a resource cache file (which carries it's sourceCache with it), it is simply instantiated with the policy data in place.
      • Is the $modx->smarty->assign() also applicable to replace $modx->getChunk() ?
          Rico
          Genius is one percent inspiration and ninety-nine percent perspiration. Thomas A. Edison
          MODx is great, but knowing how to use it well makes it perfect!

          www.virtudraft.com

          Security, security, security! | Indonesian MODx Forum | MODx Revo's cheatsheets | MODx Evo's cheatsheets

          Author of Easy 2 Gallery 1.4.x, PHPTidy, spieFeed, FileDownload R, Upload To Users CMP, Inherit Template TV, LexRating, ExerPlan, Lingua, virtuNewsletter, Grid Class Key, SmartTag, prevNext

          Maintainter/contributor of Babel

          Because it's hard to follow all topics on the forum, PING ME ON TWITTER @_goldsky if you need my help.
        • Quote from: opengeek at Feb 28, 2012, 03:30 PM

          After 2.1, there is a parser method for working with single instances of any Element which directly uses an internal cache which is loaded by cached Resources without any db hits, and reused by the parser anytime the same element is called within the same request:
          <?php
          $chunk = $modx->getParser()->getElement('modChunk', 'testSpeed');
          for ($i = 0; $i < 1000; $i++) {
              $chunk->process();
          }
          

          Note that getChunk also uses the sourceCache, but does not avoid object instantiation, and thus is not good to use iteratively like this.

          Future work on MODX will be focused on reducing the overhead of class loading, object instantiation, unnecessary parsing passes, and total code so that these bottlenecks can be more easily avoided, and using them is as efficient as including a simple file and parsing it.


          Thanks for posting this, Jason.
            Mike Reid - www.pixelchutes.com
            MODx Ambassador / Contributor
            [Module] MultiMedia Manager / [Module] SiteSearch / [Snippet] DocPassword / [Plugin] EditArea / We support FoxyCart
            ________________________________
            Where every pixel matters.
            • 36834
            • 25 Posts
            I thought I'd try to apply the methods provided by Opengeek to my particular situation. I found that in all cases I had to move the method retrieving or parsing the chunk inside the loop to prevent it caching and therefore always returning the first instance of itself. Even with $chunk->setCachable(false) the chunk still appears to be cached).

            I still ran the loop 1000x although in reality it would be nearer 20 at the most. The result shows that retrieving the chunk from the filesystem is still considerably quicker than other methods, but interestingly getObject is now the poor relation with getElement and getChunk returning similar results.

            Here are my results, with the code below. If the code is not a valid test please let me know.

            [2012-03-01 07:15:31] (INFO @ /index.php) Processed 1000 chunks using getObject = 5.1633 s
            [2012-03-01 07:15:34] (INFO @ /index.php) Processed 1000 chunks using modParser::getElement = 3.6700 s
            [2012-03-01 07:15:38] (INFO @ /index.php) Processed 1000 chunks using getChunk = 3.7573 s
            [2012-03-01 07:15:39] (INFO @ /index.php) Processed 1000 iterations on included content using modParser::processElementTags = 0.8264 s


            $ph['display_price'] = '£30,000';
            $ph['display_subtype'] = 'semi-detached house for sale';
            $ph['display_address'] = 'A House Somewhere';
            $ph['status'] = '';
            $ph['summary'] = 'This is a nice house';
            
            $y = 1000;
            
            $modx->setLogTarget(XPDO_CLI_MODE ? 'ECHO' : 'HTML');
            $modx->setLogLevel(xPDO::LOG_LEVEL_INFO);
             
            $tstart = $modx->getMicroTime();
            
            for ($i = 0; $i < $y; $i++) {
            	$ph['status'] = $i;
            	$modx->setPlaceholders($ph);
            	$chunk = $modx->getObject('modChunk', array('name' => 'testSpeed'));
            	$chunk->setCacheable(false);
                $chunk->process();
            }
            $tend = $modx->getMicroTime();
            $modx->log(modX::LOG_LEVEL_INFO, sprintf("Processed {$y} chunks using getObject = %2.4f s\n", $tend - $tstart));
            
            $tstart = $modx->getMicroTime();
            for ($i = 0; $i < $y; $i++) {
            	$ph['status'] = $i;
            	$modx->setPlaceholders($ph);
            	$chunk = $modx->getParser()->getElement('modChunk', 'testSpeed');
            	$chunk->setCacheable(false);
                $chunk->process();
            }
            $tend = $modx->getMicroTime();
            $modx->log(modX::LOG_LEVEL_INFO, sprintf("Processed {$y} chunks using modParser::getElement = %2.4f s\n", $tend - $tstart));
             
            $tstart = $modx->getMicroTime();
            for ($i = 0; $i < $y; $i++) {
            	$ph['status'] = $i;
            	$modx->setPlaceholders($ph);
                $modx->getChunk('testSpeed', $ph);
            }
            $tend = $modx->getMicroTime();
            $modx->log(modX::LOG_LEVEL_INFO, sprintf("Processed {$y} chunks using getChunk = %2.4f s\n", $tend - $tstart));
             
            $tstart = $modx->getMicroTime();
            for ($i = 0; $i < $y; $i++) {
            	$ph['status'] = $i;
            	$modx->setPlaceholders($ph);
            	$content = file_get_contents( 'propertieslistitem.chunk.tpl');
                $modx->getParser()->processElementTags('', $content);
                //echo $content;
            }
            $tend = $modx->getMicroTime();
            $modx->log(modX::LOG_LEVEL_INFO, sprintf("Processed {$y} iterations on included content using modParser::processElementTags = %2.4f s\n", $tend - $tstart));
            exit();

            • Quote from: simonp98 at Mar 01, 2012, 08:02 AM
              I thought I'd try to apply the methods provided by Opengeek to my particular situation. I found that in all cases I had to move the method retrieving or parsing the chunk inside the loop to prevent it caching and therefore always returning the first instance of itself. Even with $chunk->setCachable(false) the chunk still appears to be cached).
              Unless you change the placeholders between runs, any Element with the same tag signature will always come from the cache. You are not understanding some basics of the parsing steps.

              Hydrating objects is what is taking the time, not the parsing.
                • 36834
                • 25 Posts
                Thanks Opengeek, I have looked through modElement and modChunk and now have a basic grasp of how the tag signature is created. I also think that I can pass new properties to the chunk object using setProperties(). But this is obviously too late as the element tag is never changed and therefore the chunk is still retrieved from the source cache.
                $chunk = $modx->getObject('modChunk', array('name' => 'testSpeed'));
                $chunk->setCacheable(false);
                for ($i = 0; $i < $y; $i++) {
                	$ph['status'] = $i;
                	$chunk->setProperties($ph);
                	$chunk->process();
                }

                Is it that I can't and shouldn't be trying to use the methods you demonstrated in the way I am trying to is it just that I'm doing it wrong?
                • Quote from: simonp98 at Mar 01, 2012, 05:02 PM

                  Is it that I can't and shouldn't be trying to use the methods you demonstrated in the way I am trying to is it just that I'm doing it wrong?
                  I think you're missing the properties parameter of the process() method:


                  $chunk = $modx->getObject('modChunk', array('name' => 'testSpeed'));
                  $chunk->setCacheable(false);
                  for ($i = 0; $i < $y; $i++) {
                  	$chunk->process(array('i' => $i));
                  }


                  If I alter the test to pass in unique properties on each iteration, you can see now the additional processing time for not pulling the already processed output from the elementCache (which is where output is cached, vs. the source of the elements which is in the sourceCache).

                  My tests now result in:
                  [2012-03-01 11:31:15] (INFO) Processed 1000 chunks using getObject — 0.3535 s
                  
                  [2012-03-01 11:31:16] (INFO) Processed 1000 chunks using modParser::getElement — 0.2690 s
                  
                  [2012-03-01 11:31:18] (INFO) Processed 1000 chunks using getChunk — 2.8828 s
                  
                  [2012-03-01 11:31:19] (INFO) Processed 1000 iterations on included content using modParser::processElementTags — 0.3932 s


                  Here is the current benchmark code in a gist...
                  https://gist.github.com/1952005
                    • 36834
                    • 25 Posts
                    Thank you for your patience. I think I might not be explaining myself very well so I have put together the piece of code that might illustrate the difficulty I am having. My chunk looks like this
                    [[+status]]

                    $chunk = $modx->getObject('modChunk', array('name' => 'testSpeed'));
                    $chunk->setCacheable(false);
                    for ($i = 0; $i < $y; $i++) {
                    	echo "Pass - $i<b> ";
                    	echo '   </b>Printing chunk output ... <b>' .$chunk->process(array('status'=>$i));
                    	echo '   </b>Printing chunk content ... <b>' . $chunk->getContent();
                    	echo '   </b>Printing properties ... <b>'; print_r($chunk->_properties);
                    	echo '   </b>Printing tag ... <b>' . $chunk->_tag;
                    	echo '</b>
                    ';
                    }

                    This is what I think I'm doing ...
                    1. retrieving my 'testSpeed' chunk from the DB once.
                    2. processing my chunk in a loop, each time passing a new value for the 'status' property that increments in the loop.

                    What appears to be happening is that the tag is not changing with each new property value and so the result is that the chunk is always retrieved from the source cache.

                    Here is the result of my code
                    Pass - 0 Printing chunk output ... 0 Printing chunk content ... [[+status]] Printing properties ... Array ( [status] => 0 ) Printing tag ... [[$testSpeed?status=`0`]]
                    Pass - 1 Printing chunk output ... 0 Printing chunk content ... [[+status]] Printing properties ... Array ( [status] => 1 ) Printing tag ... [[$testSpeed?status=`0`]]
                    Pass - 2 Printing chunk output ... 0 Printing chunk content ... [[+status]] Printing properties ... Array ( [status] => 2 ) Printing tag ... [[$testSpeed?status=`0`]]
                    Pass - 3 Printing chunk output ... 0 Printing chunk content ... [[+status]] Printing properties ... Array ( [status] => 3 ) Printing tag ... [[$testSpeed?status=`0`]]
                    Pass - 4 Printing chunk output ... 0 Printing chunk content ... [[+status]] Printing properties ... Array ( [status] => 4 ) Printing tag ... [[$testSpeed?status=`0`]]
                    Pass - 5 Printing chunk output ... 0 Printing chunk content ... [[+status]] Printing properties ... Array ( [status] => 5 ) Printing tag ... [[$testSpeed?status=`0`]]
                    Pass - 6 Printing chunk output ... 0 Printing chunk content ... [[+status]] Printing properties ... Array ( [status] => 6 ) Printing tag ... [[$testSpeed?status=`0`]]
                    Pass - 7 Printing chunk output ... 0 Printing chunk content ... [[+status]] Printing properties ... Array ( [status] => 7 ) Printing tag ... [[$testSpeed?status=`0`]]
                    Pass - 8 Printing chunk output ... 0 Printing chunk content ... [[+status]] Printing properties ... Array ( [status] => 8 ) Printing tag ... [[$testSpeed?status=`0`]]
                    Pass - 9 Printing chunk output ... 0 Printing chunk content ... [[+status]] Printing properties ... Array ( [status] => 9 ) Printing tag ... [[$testSpeed?status=`0`]]
                      • 3749
                      • 24,544 Posts
                      Maybe I'm mistunderstanding you, but why do you need a chunk at all? Why not just return the appropriate output from the snippet and use a snippet tag rather than a chunk tag.


                      ---------------------------------------------------------------------------------------------------------------
                      PLEASE, PLEASE specify the version of MODX you are using . . . PLEASE!
                      MODX info for everyone: http://bobsguides.com/modx.html
                        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