Part of the EllisLab Network
   
1 of 8
1
Making CodeIgniter faster, one line at a time
Posted: 01 May 2007 12:42 PM   [ Ignore ]  
Lab Assistant
Avatar
RankRank
Total Posts:  248
Joined  02-10-2007

CI is fast. It can be faster.


system/libraries/Pagination.php - line 149


BEFORE: 10000 iterations take about 0.0529 seconds

// Add a trailing slash to the base URL if needed
$this->base_url = preg_replace("/(.+?)\/*$/", "\\1/",  $this->base_url);


AFTER: 10000 iterations take about 0.0167 seconds

// Add a trailing slash to the base URL if needed
$this->base_url = rtrim($this->base_url, '/') .'/';

 Signature 

Kohana rocks!

Profile
 
 
Posted: 01 May 2007 01:00 PM   [ Ignore ]   [ # 1 ]  
Lab Assistant
Avatar
RankRank
Total Posts:  248
Joined  02-10-2007

system/libraries/Pagination.php - line 125


BEFORE: 10000 iterations take about 0.0312 seconds

// Prep the current page - no funny business!
$this->cur_page = preg_replace("/[a-z\-]/", "", $this->cur_page);


AFTER: 10000 iterations take about 0.0046 seconds

// Prep the current page - no funny business!
$this->cur_page = (int) $this->cur_page; // even safer!

 Signature 

Kohana rocks!

Profile
 
 
Posted: 01 May 2007 04:26 PM   [ Ignore ]   [ # 2 ]  
Research Assistant
Avatar
RankRankRank
Total Posts:  722
Joined  08-06-2006

Would you put this code in the Config.php file under your optimizer?

// --------------------------------------------------------------------

    /**
     * Fetch a config file item - adds slash after item
     *
     * The second parameter allows a slash to be added to the end of
     * the item, in the case of a path.
     *
     * @access    public
     * @param    string    the config item name
     * @param    bool
     * @return    string
     */
    
function slash_item($item)
    
{
        
if ( ! isset($this->config[$item]))
        
{
            
return FALSE;
        
}

        $pref
= $this->config[$item];

        if (
$pref != '')
        
{
            
if (ereg("/$", $pref) === FALSE)
            
{
                $pref
.= '/';
            
}
        }

        
return $pref;
    
}

Profile
 
 
Posted: 01 May 2007 04:52 PM   [ Ignore ]   [ # 3 ]  
Research Assistant
RankRankRank
Total Posts:  970
Joined  04-13-2006

I think someone mentioned this before in here, about replacing unnecessary regular expression calls with something simpler and faster. Seems sensible to me. Let Derek of Allard carry our puny voices to Ellis in Wonderland.

Profile
 
 
Posted: 01 May 2007 05:24 PM   [ Ignore ]   [ # 4 ]  
Research Assistant
Avatar
RankRankRank
Total Posts:  472
Joined  09-26-2006

Let Derek of Allard carry our puny voices to Ellis in Wonderland.

ROTFLOL

Now, wiping the tears away…Nicely done Geert.

 Signature 

Old programmers never die, they just parse away.

Profile
 
 
Posted: 01 May 2007 05:37 PM   [ Ignore ]   [ # 5 ]  
Research Assistant
Avatar
RankRankRank
Total Posts:  351
Joined  07-25-2006

Good thread, I like this… The less regex that can be used, the better. Sometimes, we just don’t need all that power. wink

 Signature 

me and some random code, hosted by dh. and a blog too! ++ dead bugs

Profile
 
 
Posted: 01 May 2007 08:07 PM   [ Ignore ]   [ # 6 ]  
Administrator
Avatar
RankRankRankRankRankRank
Total Posts:  6712
Joined  03-23-2006

Great thread.

Those of your with reg-ex fu (or is that regex-fu or reg-ex-fu?).

"/(.+?)\/*$/", "\\1/"


Is the only thing this is doing is looking for a / and/or adding it?

I’ve added the second pagination fix (thanks Geert).

And hey, EllisLab is listening.  I know it seems slow, but the bug tracker is a direct result of a plan for community empowerment.  A few other things have made it all the way to the top of the foodchain, and I’m hoping to have more to announce in the near-term future.  Thanks all for your work!

 Signature 

DerekAllard.com - CodeIgniter, ExpressionEngine, and the World of Web Design
BambooInvoice - Open Source, CodeIgniter powered invoicing.

Profile
MSG
 
 
Posted: 01 May 2007 11:13 PM   [ Ignore ]   [ # 7 ]  
Summer Student
Total Posts:  17
Joined  09-20-2006

Yes, that regex will remove 0 or more ‘/’ characters from the end and add exactly one.  So the rtrim recommended will do precisely the same thing.

Thanks for listening.

Profile
 
 
Posted: 02 May 2007 01:50 AM   [ Ignore ]   [ # 8 ]  
Grad Student
Avatar
Rank
Total Posts:  92
Joined  01-29-2007

ET is correct. To further help, here is the regex broken down:

The beginning of the regex pattern:

“/

Parenthesis capture content. The dot matches any character (except for line breaks). The “+” is called a quantifier (it tells you how many time the previous element is repeated. “+” basically means “one or more”). The question mark makes it lazy (as soon as it finds its first match it stops).

(.+?)

”\/” represents a forward slash (the initial backslash is used as an escape). “*” is a quantifier like the plus sign above (it basically means “0 or more”). The dollar sign is an anchor (it represents the end).

\/*$

The ending of the regex pattern:

/”

This is what the original string is getting replaced with. The “\\1” simply means the part of the text that matched the first parenthesis (which would be all of the text except for the closing forward slash(es)). “/” just adds the closing forward slash to make sure that there is always a forward slash.

“\\1/”

I figured I would work it out for anybody who isn’t very familiar with regular expressions (they are very powerful). I highly recommend www.regular-expressions.info - it will teach you just about everything you need to know to get up and running with regex.

Hope this helps - it would be great to see it added.

@sophistry
This part of the code is doing something slightly different than what was happening in Pagination:

if (ereg("/$", $pref) === FALSE)
{
    $pref
.= '/';
}

Basically it checks if the $pref ended with a slash. If it does not, then it adds a slash.

Geert’s code mimics the regex in the Pagination file.

// Add a trailing slash to the base URL if needed
$this->base_url = rtrim($this->base_url, '/') .'/';

Basically it makes sure that $this->base_url only ends with one forward slash.

To give an example, if the input string looked like this: “asdf///” you would get different results from the two functions:

ereg result: “asdf///”
rtrim result: ““asdf/”

It is probably a minor change but I think it would probably need testing before dropping in (it’s not the exact same code just executing quicker).

As Martin mentioned, there are probably a lot of regex expressions throughout CI that could be improved.

Profile
 
 
Posted: 02 May 2007 06:05 AM   [ Ignore ]   [ # 9 ]  
Administrator
Avatar
RankRankRankRankRankRank
Total Posts:  6712
Joined  03-23-2006

ok, committed.  Thanks.

 Signature 

DerekAllard.com - CodeIgniter, ExpressionEngine, and the World of Web Design
BambooInvoice - Open Source, CodeIgniter powered invoicing.

Profile
MSG
 
 
Posted: 02 May 2007 06:07 AM   [ Ignore ]   [ # 10 ]  
Lab Assistant
Avatar
RankRank
Total Posts:  248
Joined  02-10-2007
Martin Hall - 01 May 2007 04:52 PM

I think someone mentioned this before in here, about replacing unnecessary regular expression calls with something simpler and faster.

Yup. I, amongst others, mentionned it before, in this thread for example. Great to get way more positive feedback now! Go CI!

system/helpers/string_helper.php - line 47


BEFORE: 10000 iterations take about 0.0483 seconds

function trim_slashes($str)
{
    
return preg_replace("|^/*(.+?)/*$|", "\\1", $str);
}


AFTER: 10000 iterations take about 0.0152 seconds

function trim_slashes($str)
{
    
return trim($str, '/');
}

 Signature 

Kohana rocks!

Profile
 
 
Posted: 02 May 2007 06:10 AM   [ Ignore ]   [ # 11 ]  
Administrator
Avatar
RankRankRankRankRankRank
Total Posts:  6712
Joined  03-23-2006

Ok, committed, thanks.

 Signature 

DerekAllard.com - CodeIgniter, ExpressionEngine, and the World of Web Design
BambooInvoice - Open Source, CodeIgniter powered invoicing.

Profile
MSG
 
 
Posted: 02 May 2007 06:32 AM   [ Ignore ]   [ # 12 ]  
Lab Assistant
Avatar
RankRank
Total Posts:  248
Joined  02-10-2007

Here’s another one. A code simplification rather. Most of the time simplification means optimization anyway. Explanation in the code.


system/database/drivers/mysql/mysql_driver.php - line 282


BEFORE:

function count_all($table = '')
{
    
if ($table == '')
        
// Why return a string?
        // The manual tells me this function returns an integer, and it should.
        // Drop the quotes.
        
return '0';
    
    
$query = $this->query("SELECT COUNT(*) AS numrows FROM `".$this->dbprefix.$table."`");
    
    
// A COUNT(*) query ALWAYS returns 1 row!
    // Even if the table contains no records it returns a row with "0".
    // So it is useless to check for num_rows() in this case.
    
if ($query->num_rows() == 0)
        return
'0';

    
// Low priority: the lines below can be rewritten to one line.
    // Also cast to integer, otherwise return type will be string.
    
$row = $query->row();
    return
$row->numrows;
}


AFTER:

function count_all($table = '')
{
    
if ($table == '')
        return
0;

    
$query = $this->query('SELECT COUNT(*) AS numrows FROM `'.$this->dbprefix.$table.'`');
    
    
$return (int) $query->row()->numrows;
}

 Signature 

Kohana rocks!

Profile
 
 
Posted: 02 May 2007 06:53 AM   [ Ignore ]   [ # 13 ]  
Administrator
Avatar
RankRankRankRankRankRank
Total Posts:  6712
Joined  03-23-2006

Will

$query->row()->numrows;


run on PHP 4?

 Signature 

DerekAllard.com - CodeIgniter, ExpressionEngine, and the World of Web Design
BambooInvoice - Open Source, CodeIgniter powered invoicing.

Profile
MSG
 
 
Posted: 02 May 2007 07:06 AM   [ Ignore ]   [ # 14 ]  
Lab Assistant
Avatar
RankRank
Total Posts:  248
Joined  02-10-2007

system/helpers/date_helper.php - line 88


BEFORE: 10000 iterations take about 0.1280 seconds

// From the mdate() function
$datestr = str_replace('%\\', '', preg_replace("/([a-z]+?){1}/i", "\\\\\\1", $datestr));


AFTER: 10000 iterations take about 0.1224 seconds

$datestr = str_replace('%\\', '', preg_replace('/([a-z])/i', '\\\\\\1', $datestr));

Simplified the regex a bit.

 Signature 

Kohana rocks!

Profile
 
 
Posted: 02 May 2007 07:26 AM   [ Ignore ]   [ # 15 ]  
Lab Assistant
Avatar
RankRank
Total Posts:  248
Joined  02-10-2007
Derek Allard - 02 May 2007 06:53 AM

Will

$query->row()->numrows;


run on PHP 4?

Oops, didn’t think about that. I guess that construction is not compatible with PHP 4 (can’t test it myself though).

15. Support for dereferencing objects which are returned from methods.

In PHP 4, you could not directly dereference objects which are returned from methods. You would have to first assign the object to a dummy variable and then dereference it.

PHP 4:

$dummy = $obj->method();
$dummy->method2();

PHP 5:

$obj->method()->method2();

Source: http://devzone.zend.com/node/view/id/1714#Heading4


—edit—

Oh, and by the way Derek. I noticed that throughout CI there are more occurences of these lines:

// Add a trailing slash to the base URL if needed
$image_url = preg_replace("/(.+?)\/*$/", "\\1/",  $image_url);


Would be fantastic if you searched and replaced them all with the trimr() version. To get you started, have a look in smiley_helper at lines 75 and 125.

Thanks for committing the updates Derek. grin

 Signature 

Kohana rocks!

Profile
 
 
   
1 of 8
1
 
Post Marker Legend
New Topic New posts Hot Topic Hot Topic with new posts New Poll New Poll Moved Topic Moved Topic Sticky Topic Sticky topic
Old Topic No new posts Hot Old Topic Hot Topic with no new posts Old Poll Old Poll Closed Topic Closed Topic Announcement Announcements
Theme
Change Theme
Visitor Statistics
The most visitors ever was 719, on June 06, 2008 10:16 AM
Total Registered Members: 64456 Total Logged-in Users: 20
Total Topics: 80965 Total Anonymous Users: 0
Total Replies: 435699 Total Guests: 190
Total Posts: 516664    
Members ( View Memberlist )