Jump to content

Smarty rules!


dreamwest

Recommended Posts

Lately i have been able to increase my sites performance with smarty by well over 500%.

 

I can build apps in a fraction of the time than traditional scripting and enjoy the performance, i can assign a simple query:

 

while ($row = mysql_fetch_assoc( $result )){

$show_content[] = $row;
}
$smarty->assign( 'show_content', $show_content );

 

and pull bits and pieces out separating content and code

 

{$show_content[i].field}

 

Its all so simple and flexible - I lov it!

 

I think this can go in my hall of fame for best apps

 

1. BING

2. Smarty

3. Avant browser

Link to comment
Share on other sites

Lately i have been able to increase my sites performance with smarty by well over 500%.

 

Given that smarty is compiled into PHP, the performance increase is probably just because your old code sucked. No offense.

 

I'm entirely unimpressed by template engines. Taken straight from "Why Use Smarty?" is this example:

<table>
   {section name=art loop=$article}
      <tr>
         <td>{$article[art].headline}<td>
         <td>{$article[art].date}<td>
         <td>{$article[art].author}<td>
      </tr>
   {/section}
</table>

 

Can you tell me how this gives me any benefit over this?

<table>
   <?php foreach ($articles as $article): ?>
      <tr>
         <td><?php echo $article['headline'] ?><td>
         <td><?php echo $article['date'] ?><td>
         <td><?php echo $article['author'] ?><td>
      </tr>
   <?php enforeach ?>
</table>

 


 

Here is a quick little benchmark I decided to make. Each time we'll use ab with 1000 requests and a concurrency of 10. This is on Windows 7, PHP 5.3, Apache 2.2.11 and MySQL 5.1.36. No PHP accelerator/opcode cache is installed.

 

First I'm going to test just the loading of Smarty.

 

static_smarty.php:

<?php
require './lib/Smarty.class.php';

echo 'Hello World';

 

static_plain:

<?php
echo 'Hello World';

 

Testing the Smarty version we'll get:

C:\Users\daniel>ab -c 10 -n 1000 http://localhost/smarty_test/static_smarty.php
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests


Server Software:        Apache/2.2.11
Server Hostname:        localhost
Server Port:            80

Document Path:          /smarty_test/static_smarty.php
Document Length:        11 bytes

Concurrency Level:      10
Time taken for tests:   2.574 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      197000 bytes
HTML transferred:       11000 bytes
Requests per second:    388.48 [#/sec] (mean)
Time per request:       25.741 [ms] (mean)
Time per request:       2.574 [ms] (mean, across all concurrent requests)
Transfer rate:          74.74 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.6      0       6
Processing:     5   25   3.0     25      42
Waiting:        3   25   3.0     25      42
Total:          5   25   3.0     25      42

Percentage of the requests served within a certain time (ms)
  50%     25
  66%     26
  75%     27
  80%     27
  90%     29
  95%     30
  98%     32
  99%     35
100%     42 (longest request)

 

And next the plain version:

C:\Users\daniel>ab -c 10 -n 1000 http://localhost/smarty_test/static_plain.php
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests


Server Software:        Apache/2.2.11
Server Hostname:        localhost
Server Port:            80

Document Path:          /smarty_test/static_plain.php
Document Length:        11 bytes

Concurrency Level:      10
Time taken for tests:   0.656 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      197000 bytes
HTML transferred:       11000 bytes
Requests per second:    1524.30 [#/sec] (mean)
Time per request:       6.560 [ms] (mean)
Time per request:       0.656 [ms] (mean, across all concurrent requests)
Transfer rate:          293.25 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.5      0       3
Processing:     2    6   1.3      6      13
Waiting:        2    6   1.3      6      12
Total:          2    6   1.3      6      13

Percentage of the requests served within a certain time (ms)
  50%      6
  66%      7
  75%      7
  80%      7
  90%      8
  95%      9
  98%     10
  99%     10
100%     13 (longest request)

 

Now we'll try doing something that is actually useful. For this purpose I've imported the PHP Freaks tutorials into my local database and the scripts will be listing the tutorials.

 

This time we'll have an init file that opens a connection to the database and fetches the info (just so I didn't have to type it twice).

 

mysqltable_init.php:

<?php
$db = new PDO('mysql:host=localhost;dbname=test', 'root', '******');

$stmt = $db->query('SELECT content_id, title, permalink, summary, created_at FROM content ORDER BY created_at DESC');

 

mysqltable_smarty.php:

<?php
require './lib/Smarty.class.php';
require './mysqltable_init.php';

$smarty = new Smarty();
$smarty->assign('tutorials', $stmt->fetchAll());

$smarty->display('mysqltable.tpl');

 

mysqltable.tpl (Smarty template):

<h1>PHP Freaks Tutorials</h1>

{section name=tut loop=$tutorials}
<div class="tutorial" id="tut-{$tutorials[tut].content_id}">
<h2>{$tutorials[tut].title|escape}</h2>

<small>{$tutorials[tut].created_at|date_format:"%B %e, %Y, %H:%M"}</small>

<div class="summary">
	{$tutorials[tut].summary|escape}
</div>

<a href="http://www.phpfreaks.com/tutorial/{$tutorials[tut].permalink}">Read more</a>
</div>
{/section}

 

mysqltable_plain.php:

<?php
require './mysqltable_init.php';

echo '<h1>PHP Freaks Tutorials</h1>';
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
echo '<div class="tutorial" id="tut-' . $row['content_id'] . '">'
   . '<h2>' . htmlentities($row['title']) . '</h2>'
   . '<small>' . date('F j, Y, H:i', strtotime($row['created_at'])) . '</small>'
   . '<div class="summary">' . htmlentities($row['summary']) . '</div>'
   . '<a href="' . htmlentities($row['permalink']) . '">Read more</a>'
   . '</div>';
}

 

First we benchmark the Smarty version:

C:\Users\daniel>ab -c 10 -n 1000 http://localhost/smarty_test/mysqltable_smarty.php
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests


Server Software:        Apache/2.2.11
Server Hostname:        localhost
Server Port:            80

Document Path:          /smarty_test/mysqltable_smarty.php
Document Length:        9574 bytes

Concurrency Level:      10
Time taken for tests:   7.677 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      9740000 bytes
HTML transferred:       9574000 bytes
Requests per second:    130.25 [#/sec] (mean)
Time per request:       76.774 [ms] (mean)
Time per request:       7.677 [ms] (mean, across all concurrent requests)
Transfer rate:          1238.92 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    1   2.4      0      27
Processing:    13   75  30.1     72     265
Waiting:       13   73  29.9     69     265
Total:         14   76  30.0     73     265

Percentage of the requests served within a certain time (ms)
  50%     73
  66%     84
  75%     93
  80%     98
  90%    117
  95%    132
  98%    146
  99%    159
100%    265 (longest request)

 

And the plain PHP version:

C:\Users\daniel>ab -c 10 -n 1000 http://localhost/smarty_test/mysqltable_plain.php
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests


Server Software:        Apache/2.2.11
Server Hostname:        localhost
Server Port:            80

Document Path:          /smarty_test/mysqltable_plain.php
Document Length:        8232 bytes

Concurrency Level:      10
Time taken for tests:   2.984 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      8398000 bytes
HTML transferred:       8232000 bytes
Requests per second:    335.10 [#/sec] (mean)
Time per request:       29.842 [ms] (mean)
Time per request:       2.984 [ms] (mean, across all concurrent requests)
Transfer rate:          2748.22 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.4      0       3
Processing:     6   29  10.3     29      83
Waiting:        5   29  10.3     28      82
Total:          7   30  10.3     29      83

Percentage of the requests served within a certain time (ms)
  50%     29
  66%     33
  75%     36
  80%     38
  90%     43
  95%     48
  98%     54
  99%     57
100%     83 (longest request)

 


 

Results:

 

Test name: Static

[/td]

Requests per second

Total time (seconds)

Plain PHP

1524.3

0.656

Smarty

388.48

2.574

 

Here it takes a lot more time just loading Smarty.

 

 

Test name: MySQL table

[td]Requests per second

Total time (seconds)

Plain PHP

335.10

2.984

Smarty

130.25

7.677

 

Here our plain PHP version that actually does something is only a little slower than the Smarty version that doesn't do anything. Smarty is of course slower than PHP here as well.

Link to comment
Share on other sites

C:\Users\daniel>ab -c 10 -n 1000 http://localhost/smarty_test/mysqltable_smarty.php
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests


Server Software:        Apache/2.2.11
Server Hostname:        localhost
Server Port:            80

Document Path:          /smarty_test/mysqltable_smarty.php
Document Length:        9574 bytes

Concurrency Level:      10
Time taken for tests:   7.575 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      9740000 bytes
HTML transferred:       9574000 bytes
Requests per second:    132.01 [#/sec] (mean)
Time per request:       75.754 [ms] (mean)
Time per request:       7.575 [ms] (mean, across all concurrent requests)
Transfer rate:          1255.60 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    1   2.1      0      15
Processing:    17   74  26.4     71     209
Waiting:       15   73  26.5     69     207
Total:         19   75  26.3     72     209

Percentage of the requests served within a certain time (ms)
  50%     72
  66%     83
  75%     90
  80%     96
  90%    112
  95%    124
  98%    139
  99%    154
100%    209 (longest request)

 

More or less the same.

Link to comment
Share on other sites

I notice you're still calling Avant a browser  ::)

 

If wikipedia says it is - it is  http://en.wikipedia.org/wiki/Avant_Browser  :(:shy:;):D:P

 

C:\Users\daniel>ab -c 10 -n 1000 http://localhost/smarty_test/mysqltable_smarty.php
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests


Server Software:        Apache/2.2.11
Server Hostname:        localhost
Server Port:            80

Document Path:          /smarty_test/mysqltable_smarty.php
Document Length:        9574 bytes

Concurrency Level:      10
Time taken for tests:   7.575 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      9740000 bytes
HTML transferred:       9574000 bytes
Requests per second:    132.01 [#/sec] (mean)
Time per request:       75.754 [ms] (mean)
Time per request:       7.575 [ms] (mean, across all concurrent requests)
Transfer rate:          1255.60 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    1   2.1      0      15
Processing:    17   74  26.4     71     209
Waiting:       15   73  26.5     69     207
Total:         19   75  26.3     72     209

Percentage of the requests served within a certain time (ms)
  50%     72
  66%     83
  75%     90
  80%     96
  90%    112
  95%    124
  98%    139
  99%    154
100%    209 (longest request)

 

More or less the same.

 

It doesnt make sense - ive tested normal code against smarty. My pages load within 1 second with smarty and has over 800 lines (formatted) of code. Smarty is slower without compile check because every time a page is viewed it checks to see if the file has been modified. So once youve finished designing the site use

 

$smarty->compile_check = false;

 

before displaying the templates and wella like magic

 

So instead of running this all the time:

 

<?php
require './mysqltable_init.php';

echo '<h1>PHP Freaks Tutorials</h1>';
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
   echo '<div class="tutorial" id="tut-' . $row['content_id'] . '">'
      . '<h2>' . htmlentities($row['title']) . '</h2>'
      . '<small>' . date('F j, Y, H:i', strtotime($row['created_at'])) . '</small>'
      . '<div class="summary">' . htmlentities($row['summary']) . '</div>'
      . '<a href="' . htmlentities($row['permalink']) . '">Read more</a>'
      . '</div>';
}

 

It only compiling the php page :

 

<?php
$db = new PDO('mysql:host=localhost;dbname=test', 'root', '******');

$stmt = $db->query('SELECT content_id, title, permalink, summary, created_at FROM content ORDER BY created_at DESC');

 

because the template is already compiled

 

Dont belive me? I dare you to try it in a real application, generate the template first by going to the php page then any further requests by anyone will be SUPA fast

 

 

Link to comment
Share on other sites

dreamwest, give it up. Template engines simply add another unneeded layer.

 

I fail to see any benefits.

 

I think this can go in my hall of fame for best apps

 

1. BING

2. Smarty

3. Avant browser

 

I swear your listing this just to get people offside. You can't possibly be serious.

Link to comment
Share on other sites

I think this can go in my hall of fame for best apps

 

1. BING

2. Smarty

3. Avant browser

 

I swear your listing this just to get people offside. You can't possibly be serious.

 

Hell yeah!

 

Bing for president!

Smarty for Vice President (pffft, Palin has got nothing on Smarty.. she's not even smart, let alone smart-y)

And Avant for National Security (think avant-guard)!

Link to comment
Share on other sites

because the template is already compiled

 

Dont belive me? I dare you to try it in a real application, generate the template first by going to the php page then any further requests by anyone will be SUPA fast

 

"Compiling: Smarty compiles templates into PHP code behind the scenes, eliminating run-time parsing of templates."

 

 

Source: http://www.smarty.net/rightforme.php

 

 

So, VERY best case, it will be slightly slower than a non-Smarty using page.  (Slightly slower because the Smarty class must be parsed by the PHP core, then the object created and a few methods called, then the 'compiled' page has to be included.)

 

As Daniel showed though, just loading the Smarty library takes quite a bit of time though.

Link to comment
Share on other sites

It doesnt make sense - ive tested normal code against smarty. My pages load within 1 second with smarty and has over 800 lines (formatted) of code. Smarty is slower without compile check because every time a page is viewed it checks to see if the file has been modified. So once youve finished designing the site use

 

$smarty->compile_check = false;

 

before displaying the templates and wella like magic

 

No, it's actually turned into this monstrous piece of code (that is the cached version):

 

<?php /* Smarty version 2.6.26, created on 2009-08-22 12:59:29
         compiled from mysqltable.tpl */ ?>
<?php require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
smarty_core_load_plugins(array('plugins' => array(array('modifier', 'escape', 'mysqltable.tpl', 5, false),array('modifier', 'date_format', 'mysqltable.tpl', 7, false),)), $this); ?>
<h1>PHP Freaks Tutorials</h1>

<?php unset($this->_sections['tut']);
$this->_sections['tut']['name'] = 'tut';
$this->_sections['tut']['loop'] = is_array($_loop=$this->_tpl_vars['tutorials']) ? count($_loop) : max(0, (int)$_loop); unset($_loop);
$this->_sections['tut']['show'] = true;
$this->_sections['tut']['max'] = $this->_sections['tut']['loop'];
$this->_sections['tut']['step'] = 1;
$this->_sections['tut']['start'] = $this->_sections['tut']['step'] > 0 ? 0 : $this->_sections['tut']['loop']-1;
if ($this->_sections['tut']['show']) {
    $this->_sections['tut']['total'] = $this->_sections['tut']['loop'];
    if ($this->_sections['tut']['total'] == 0)
        $this->_sections['tut']['show'] = false;
} else
    $this->_sections['tut']['total'] = 0;
if ($this->_sections['tut']['show']):

            for ($this->_sections['tut']['index'] = $this->_sections['tut']['start'], $this->_sections['tut']['iteration'] = 1;
                 $this->_sections['tut']['iteration'] <= $this->_sections['tut']['total'];
                 $this->_sections['tut']['index'] += $this->_sections['tut']['step'], $this->_sections['tut']['iteration']++):
$this->_sections['tut']['rownum'] = $this->_sections['tut']['iteration'];
$this->_sections['tut']['index_prev'] = $this->_sections['tut']['index'] - $this->_sections['tut']['step'];
$this->_sections['tut']['index_next'] = $this->_sections['tut']['index'] + $this->_sections['tut']['step'];
$this->_sections['tut']['first']      = ($this->_sections['tut']['iteration'] == 1);
$this->_sections['tut']['last']       = ($this->_sections['tut']['iteration'] == $this->_sections['tut']['total']);
?>
<div class="tutorial" id="tut-<?php echo $this->_tpl_vars['tutorials'][$this->_sections['tut']['index']]['content_id']; ?>
">
<h2><?php echo ((is_array($_tmp=$this->_tpl_vars['tutorials'][$this->_sections['tut']['index']]['title'])) ? $this->_run_mod_handler('escape', true, $_tmp) : smarty_modifier_escape($_tmp)); ?>
</h2>

<small><?php echo ((is_array($_tmp=$this->_tpl_vars['tutorials'][$this->_sections['tut']['index']]['created_at'])) ? $this->_run_mod_handler('date_format', true, $_tmp, "%B %e, %Y, %H:%M") : smarty_modifier_date_format($_tmp, "%B %e, %Y, %H:%M")); ?>
</small>

<div class="summary">
	<?php echo ((is_array($_tmp=$this->_tpl_vars['tutorials'][$this->_sections['tut']['index']]['summary'])) ? $this->_run_mod_handler('escape', true, $_tmp) : smarty_modifier_escape($_tmp)); ?>

</div>

<a href="http://www.phpfreaks.com/tutorial/<?php echo $this->_tpl_vars['tutorials'][$this->_sections['tut']['index']]['permalink']; ?>
">Read more</a>
</div>
<?php endfor; endif; ?>

 

This is the code that is being run each time. There is no "magic" going on.

 

The only thing compile_check does is that it checks if the template file has been modified. If you disable that then you disable the check. It can be used in a production environment because the template is unlikely to change very often there. Don't believe me? I dare you to read the manual. It'll be SUPA clear to you.

 

Give it up or come up with some real arguments or evidence.

Link to comment
Share on other sites

Well there is an advantage to using smarty - it increases developer productivity. But to be quite honest, I would just use plain php. Not only because of performance, but also because adding new employees on board the team would be easy. Not every php programmer knows smarty, but they do know plain php - DUH!

Link to comment
Share on other sites

Not only because of performance, but also because adding new employees on board the team would be easy. Not every php programmer knows smarty, but they do know plain php - DUH!

 

 

Well, one of the arguments for using a template engine is that "designers don't always know PHP, and a template engine allows one to better separate PHP and HTML."  But, some designers don't know custom Smarty markup either haha.

 

 

 

@Daniel:

 

 

Wow....  So apparently compiled Smarty code = fail.  The first thing that jumps out at me is this:

 

smarty_core_load_plugins(array('plugins' => array(array('modifier', 'escape', 'mysqltable.tpl', 5, false),array('modifier', 'date_format', 'mysqltable.tpl', 7, false),)), $this);

 

 

Since the file is included inside of a method, that means that there is the potential for the same plugins to be loaded over and over again.

Link to comment
Share on other sites

No, it's actually turned into this monstrous piece of code (that is the cached version):

 

Yeah i know - you should see my compiled code, some pages are over 2000 lines. But regardless of this and the extra requests i bet you saw a decrease in frontend page loading time

 

I went from having 10+ second loading times to < 1 second +- 0.5 seconds - thats what gets me excited

 

Wow....  So apparently compiled Smarty code = fail.  The first thing that jumps out at me is this:

 

smarty_core_load_plugins(array('plugins' => array(array('modifier', 'escape', 'mysqltable.tpl', 5, false),array('modifier', 'date_format', 'mysqltable.tpl', 7, false),)), $this);

 

Since the file is included inside of a method, that means that there is the potential for the same plugins to be loaded over and over again.

 

Ill look into this...Im sure they wouldnt allow this bug

Link to comment
Share on other sites

I went from having 10+ second loading times to < 1 second +- 0.5 seconds - thats what gets me excited

 

That is not evidence it's because of Smarty. As I said previously, your old code probably sucked. If you had loading times of over 10 seconds, then I find that reasonably ostensible. Did you ever profile it to figure out where the bottleneck was?

Link to comment
Share on other sites

Agree, template engines add overhead to an application. However as a previous post mentioned they make it much easier for a designer to work with when your code gets handed over. Code within templates is usually (should be) minimal consisiting of array loops. These areas are best commented for the designers benefit and the tags should be left untouched. When output is embeded in php files I usually end up with many issues when a designer takes over. IMO this is the only benefit of a template engine. They should not be written off alltogether.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.