Welcome Guest, Not a member yet? Register   Sign In
CodeIgniter Optimization!
#1

[eluser]optocus[/eluser]
Hi,

I was wondering how optimized CI is. I have read benchmarks and it seems it's better than all the other frameworks out there but I still find it to be a bit slow. Did anybody tried to optimize it even further? I am referring here to CI itself not the application developed with it. So don't give me suggestions on how to optimize my own code because that's not what I'm looking for.

Thank you.
#2

[eluser]Michael Wales[/eluser]
It's pretty well optimized - you can look over the EllisLabs Developer Guidelines which outline a lot of little thing EllisLabs does to optimize it's code.

A great read, not only for CI, but for your own coding as well.
#3

[eluser]Web Editors[/eluser]
optocus,

CI is a monolithic framework and it loads a heck of a lot of stuff on every request. overall, it seems to be the best framework out in my opinion and would work great on small to medium sites. I am currently going through it and stripping out all the stuff I do not want. I guess what I would prefer myself is to only utilize the db, sessions, and routers and somehow have the ability to just include any of the other features when I need them. Too bad they did not come out with a version like this. If anyone has already done anything similar this please let me know.
#4

[eluser]tonanbarbarian[/eluser]
it may seem like CI loads a lot of things, and yes if you look at the included files it does load several even if your application is just a basic controller with a single view.

However the benchmarking I have done shows it to be excellent.

I built a fairly straight forward app in Cake, about 8 admin form with pagination etc. Cake 1.1 took 4M of memory to display an admin form only shows 2 records. Cake 1.2 took 5M to do the same. And was loading about 50 include files

I rewrote the same thing in CI, but added even more functionality to it. I am able to load so much more of the system conditionally in CI so it is using a staggeringly less amount of memory, 1.5M to display lists of records not just with pagination, but with filtering and storing of the filters and pagination information in the session, something I had not yet put into the Cake version. And it is loading a similar number of files.

CI may load several files to do some things, but those files are fairly small and are using a lot less memory than some other frameworks. And I am not sure it would be possible to make anything conditional that is currently included.

I think CI is very well optimised
#5

[eluser]optocus[/eluser]
I am currently working on a social community website (that could become very popular) and the homepage (most database intensive page) loads in 0.13s (7pages/second). This is a great improvement due to the new PC I have bought (AMD Athlon64 X2 4000+, 2GB 800MHz DDR2 RAM, WD2500YS SATA HDD). The old PC was generating only 3 pages/second (AMD Athlon XP 2200+, 896MB 400MHz DDR RAM, IDE HDD). I assume on a dedicated server with MySQL query caching and maybe APC or some other caching sistem for the scripts will deliver much more pages/second). The CI internals load in 0.02 seconds on my new PC. That means about 50+ pages/second for a "hello world" controller.

Leaving the hardware and cache optimization aside, CI does lots of stuff in an unoptimized manner. Yes, it is way faster than any other framework but improvements could be done.

First of all I want to point out something that I discovered and I would have not anticipated. In a framework a great time is spent including files. If you include just a few files (let's say 5 files) it's fast, but if you want to include 50 files you will notice it takes a lot of time. I did a benchmark on including 20 php files that each contained a class and it took much more time than i would have thought (0.03s). CI loads lots of files. There are the config files, library files, view files (which could be many), etc. They all add up and slow things down.

Other things that are slower than they could be are the variable retrivals. Doing $this->config->item('base_url'); instead of $config['base_url'] is slower. Personally I also find it annoying to tipe that much to get a config value.

Using CI ActiveRecord class to generate queries is also slower than just building your query in a string. But it has it's advantages also Smile

Personally the routing feature is a bit of overkill since we can use .htaccess and mod_rewrite for that (for those who can't i suggest you find a real host Tongue).

Happily CI is overall very helpful and I can live with those things that I don't like. Also in real life most of the sites we build are not so popular to have to handle a huge ammount of requests. I read once that del.icio.us is built on top of Symfony (which is SLOW SLOW SLOW) so I guess if one of my sites will ever get that popular it won't be too hard to modify CI to handle the requests.

newbie, please let me know when you finish with the modifications. I would like to see what improvments you have done.
#6

[eluser]Web Editors[/eluser]
optocus,

Yeah, you will notice a huge difference once you stick the code on a a nice machine - I am currently working on a slow machine for dev and it is killing me. I having been looking at the CI source code quite extensively and there are too many conditions that I would not personally use - when you have an app that will install and run in any environment you will need this. But the apps we normally build will never ever move from it's environment - this is key for fast applications. I need to insure this is as fast as possible - it will expect 50 million hits a day (most in a 3 hour period) - so in my case less is more.


I really liked the CI MVC style so I decided to rewrite it for only a unix server. I pretty much have a lot libs from the last 10+ years that I want to pop in too. Everything start with the URI routing - where when you hit "/products/chairs/" on the server it will load the appropriate controller. I like this because you can enforce the MVC pattern and minimize spaghetti code. I decided to only do the URI routing and grab my paramters the way I normally do. It is pretty basic and easy to understand - it uses the same htaccess and index file (stripped down) as CI and directory structure is similar too.


So when I complete it I can take this framework and use it from one project to the next. It will also give you the option to load multiple front_end controllers if for some reason or another you need to bypass it - you never know. it is single point of entry (monolithic) script, but so transparent it is like it never existed. primary functionality will exist in the page controllers where it is redirected - that is where my main logic will exist.


Anyways - here is the nearly completed frontpage controller; This is not a mod for CI it is custom... now I need to see if I can easily use some of the helpers/libraries easily.


$_front_controller = new FrontController();
$_page_controller = new $_front_controller->page_controller_class_name($_front_controller);

class FrontController
{
private $controller_file;
private $controller_path;
private $controller;
public $page_controller_class_name;
private $view_path;
private $model_path;
/**
*
*/
public function __construct()
{
$this->controller_file = $this->_GetController();
$this->controller_path = APPPATH . 'controllers/' . $this->controller_file . EXT;
$this->_SetController();
}
/**
*
*/
private function _GetController()
{
$arg_path;
if(!(isset($_SERVER['PATH_INFO']))) { $arg_path = "/"; }
else { $arg_path = $_SERVER['PATH_INFO']; }
$path = ltrim($arg_path, '/');
$path = rtrim($path, '/');
if($path == '') { return DEFAULT_CONTROLLER; }
else { return $path; }
}
/**
*
*/
private function _SetController()
{
$this->page_controller_class_name = ucfirst($this->controller_file);
if (file_exists($this->controller_path))
{
require ($this->controller_path);
}
else
{
$this->_ShowError('error_404','ERROR 404','Controller not found. Please try again or <a href="/">start over</a>');
}
}
/**
*
*/
public function _LoadView($view_dir)
{
$this->view_path = APPPATH . 'views/' . $view_dir . '/view' . EXT;
if (file_exists($this->view_path))
{
require ($this->view_path);
}
else
{
$this->_ShowError('error_404','ERROR 404','View not found. Please try again or <a href="/">start over</a>');
}
}
/**
*
*/
public function _LoadModel($model_file)
{
$this->model_path = APPPATH . 'models/' . $model_file . EXT;
if (file_exists($this->model_path))
{
require ($this->model_path);
}
else
{
$this->_ShowError('error_404','ERROR 404','Model not found. Please try again or <a href="/">start over</a>');
}
}
/**
*
*/
private function _ShowError($type, $heading, $message)
{
$my_error = BASEPATH . 'errors/' . $type . EXT;
require ($my_error);
}
}
#7

[eluser]tonanbarbarian[/eluser]
The reason that it takes so long to retrieve the data from the config
Code:
$this->config->item(’base_url’);
rather than doing something like
Code:
$config[’base_url’];
is that function calls are orders of magnitude slower.
that is why it is always better to do something like
Code:
if ($var===null)
rather than
Code:
if (is_null($var))

And if you are expecting a large number of hits, and you are finding that you are wanting to modify the core of CI a lot to optimise then I would suggest you are probably better of building your own MVC framework from scratch. I have seen examples of very simple but effective MVC class frameworks online (cannot remember where exactly it was months ago)

Another thing you might want to consider when writing your code if you want optimal performance is not include the closing php tag at the end of the file.
Each time the PHP interpreter comes across an opening or closing PHP tag it has to take some time to switch from PHP process to HTML process and back again.
So if you have a closing php tag at the end of each of your files PHP will switch to HTML processing mode when it might not need to, particularily since most of your code files will be starting with an opening PHP tag

i.e.
BAD
Code:
&lt;?php
...
...
?&gt;

GOOD
Code:
&lt;?php
...
...

This also means that in your views if you are going to have several variables displayed near each other think about using a single echo statement for all of them rather than individual ones in seperate tag blocks

BAD
Code:
<div>&lt;?php echo $site; ?&gt;::&lt;?php echo $form; ?&gt;</div>
<div>
  &lt;?php echo form_open(); ?&gt;
  &lt;?php echo form_input('test'); ?&gt;
  &lt;?php echo form_input('something'); ?&gt;
  &lt;?php echo form_submit('go'); ?&gt;
  &lt;?php echo form_close(); ?&gt;
</div>

GOOD
Code:
<div>&lt;?php echo $site.'::'.$form; ?&gt;</div>
<div>
  &lt;?php
  echo form_open();
  echo form_input('test');
  echo form_input('something');
  echo form_submit('go');
  echo form_close();
  ?&gt;
</div>

And lastly try to use single quotes rather than double quotes if you can. Because double quotes have to be parsed to see if there are variables in the string, where as single quotes do not.
#8

[eluser]Mark van der Walle[/eluser]
There was some other stuff I noticed when looking through the source code. I noticed booleans are written in uppercase (TRUE|FALSE) instead of lowercase (true|false). Using the lowercase version is marginally faster. Also the use of single quotes versus double quotes. Single quotes should be used almost always since PHP can parse this faster.

While the impact of this is low I think CI should do anything possible to speed up the code.
#9

[eluser]xwero[/eluser]
[quote author="tonanbarbarian" date="1196652880"]
BAD
Code:
<div>&lt;?php echo $site; ?&gt;::&lt;?php echo $form; ?&gt;</div>
<div>
  &lt;?php echo form_open(); ?&gt;
  &lt;?php echo form_input('test'); ?&gt;
  &lt;?php echo form_input('something'); ?&gt;
  &lt;?php echo form_submit('go'); ?&gt;
  &lt;?php echo form_close(); ?&gt;
</div>
[/quote]

I understand what you are trying to demonstrate but if you have a form and you use the form helper functions you can't avoid separated php code because most/all of the time the form is more than only input fields.
An if page rendering performance is involved the less php generated html (helper functions) you have the better.
#10

[eluser]tonanbarbarian[/eluser]
yes thats true
you need to come to your own balance as to how many helper functions to use vs straight html etc




Theme © iAndrew 2016 - Forum software by © MyBB