I am going to start using codeigniter, but since it only offers to cache everything or nothing (which would not work, because I have logins, and other areas which cannot be cached) I was wondering whether it is a good idea to use Smarty.
The only concern I have in this question is speed. (No yes/no smarty general question.)
My Question:
CodeIgniter with some db queries (blog, loading data for pages from the database, etc.)
vs.
CodeIgniter + same db + smarty + partial caching (and of course if smarty->is_cached(.tpl) do not do any db requests)
What is fast, what should I use. Are there any smarty-benchmarks I did not see? Starting at how many db request, would you say, smarty improves performance noticeable considering you have to also load the smarty library?
Thanks in advance.
Premature optimization is the root of all evil. I'd suggest not to worry about caching unless your application is done. Then see how it performs by profiling it with xdebug or Zend_Debugger and do some load tests with ab. Use an opcode cache if you can.
If you think the app is too slow then, consider page/partials caching. You dont want caching for caching's sake, but to locate and remove bottlenecks. If you feel comfortable with Smarty and want to use it as template engine, well, use it. If you dont need a template engine, you could also use Zend_Cache with APC or memcached for caching.
Smarty or any template system is another layer of complexity. It comes with overload not with performance increase, even when cached. Its advantages are others, like easiness to develop with.
Why not implementing your own caching method? It's not that hard.
I'm using both Smarty and CodeIgniter in different projects. They are both very fine libraries, but I've never felt the need to combine them.
A caching method could use CI's hooks: pre_system to see, if there is a whole page cached, post_controller to intercept the calls to the views and ... just scanning the CI user guide. There is a hook 'cache_override'. I suppose you could use this too.
Related
I have an existing php website, that is written in an old fashion way.
Every page has the same pattern
<?php
require_once("config.php");
//Some code
require_once("header.php");
?>
Some HTML and PHP code mixture
<?php
require_once("footer.php");
?>
Where all the db connection, session data, language files are initiated at the "config.php" file.
And every DB access is done with a mysql_query call,
No OOP what-so-ever, purely procedural programming.
How would you to optimize this code structure in order to improve performance and make this website robust enough to handle heavy traffic ?
How would you to optimize this code structure in order to improve performance and make this website robust enough to handle heavy traffic ?
The structure you've shown us has very little scope for for optimization. Making it object-oriented will make it slower than it currently is. Note that the code within the included files may benefit greatly from various changes.
There's only 3 lines of code here. So not a lot of scope for tuning. The _once constructs add a (tiny) overhead, as does use of require rather than include - but this is a very small amount compared to what's likely to be happening in the code you've not shown us.
Where all the db connection, session data, language files are initiated at the "config.php" file
There are again marginal savings by delaying access to external resources until they are needed (and surrendering access immediately when they are no longer required) - but this is not an OO vs procedural issue.
Why will OO be slower?
Here the routing of requests is implemented via the the webserver - webservers are really good at this and usually very, very efficient. The alternative approach of using a front controller gives some scope for applying templating in a more manageable way and for applying late patching of the content (although it's arguable if this is a good idea). But using a front-controller pattern is not a requirement for OO.
Potentially, when written as OO code, redundant memory allocations hang around for longer - hence the runtime tends to have a larger memory footprint.
Overriding and decorating adds additional abstraction and processing overhead to the invocation of data transformations.
every DB access is done with a mysql_query call
There's several parts to this point. Yes, the mysql_ extension is deprecated and you should be looking to migrate this as a priority (sorry, but I can't recommend any good forward/backward shims) however it is mostly faster than the mysqlnd engine - the latter has a definite performance advantage with large datasets / high volume due to reduced memory load.
You seem to be convinced that there's something inherently wrong with procedural programming with regard to performance and scale. Nothing could be further from the truth. G-Wan, Apache httpd, Varnish, ATS, the Linux kernel are all written in C - not C++.
If you want to improve performance and scalability, then you're currently looking in the wrong place. And the only way to make significant in-roads is to to profile your code under relevant load levels.
If you really don't want to change your structure (OOP and mysql_*..., and even with these in fact), you should implement a cache system, to avoid the generation of content everytime. If you have some data that doesn't change often (like blog post, news or member profile), you can create a cache of 5 minutes on it, to lighten the SQL use. Google might help you for this.
There's also a lot of web techniques to optimize pages loading: use a CDN to load your static ressources, Varnish cache...
With PHP itself, there's also some methods, but a lot of blog post exists about that, just look here for example :) For example:
Avoid regex if possible
Initialize variable if you need it: it's 10 times slower to increment/decrement an non-initialized variable (which is ugly btw)
Don't call functions in for declaration, make temp variable instead
etc.
Don't hesitate to benchmark, make some tests with JMeter to simulate a pool of connections and see which page is slow and what you should optimize first.
BACKSTORY
I maintain a spectrum of (web-)applications that all use a large homegrown PHP library. Some of these applications are traditional desktop applications that are used by employees, but others (which are also more relevant to this question), are PHP websites for which performance is becoming a more important issue as the popularity continues to grow.
CURRENT PHP CACHING METHODS
To speed up one of our websites (it's a shop, think of it as thinkgeek.com), i employ memcached to cache certain segments of the website that don't require constantly being dynamicly build (such as the product listing for a certain category).
We also use a pretty much factory-default installation of APC as an OPCode cache.
Both of these methods bring significant improvements to the website's performance, but i'm very much looking to go further down the road of optimisation.
Function Volatility in PHP
Coming from a Database background myself, i'm very fond of how PostgreSQL for example, uses function volatility to get massive performance gains while maintaining reliable and accurate results.
My question is, is there any extension to PHP that allows the developer to mark certain functions (or class methods) as IMMUTABLE? (meaning the result of that function is always the same, when given the same input arguments). This caching extension could then cache the result of that function which should result in massive performance gains when using big libraries of code.
A simple example would be a method such as SomeClass::getWebsiteFooter(); which returns some HTML code that's always the same, unless the website has been altered (in which case the cache would be flushed).
Does something like this exist ? I haven't been able to find anything remotely similar on the market. Are there any other methods of performance improvement that might benefit my situation ?
I would say you have look at php application as a web application and implement several levels of caching.
IMMUTABLE methods - I don't think is good approach. Usage of caching on db level, application level (memcached) is good start.
Then I would suggest caching on view level Smarty caching and caching proxy like Squid or Varnish
I am working on a Facebook game which is developed using Zend framework. Right now I don't have lots of traffic and already seen quite a large # of data usage / CPU time.
Actually, I'm not good at Zend. I good at coding from scratch for both PHP & JS.
so, I am curious about the performance of Zend framework. becuase I'm thinking about rebuilding the applciation using Zend as the backend to manage the data / session / logic. and use JS (native code or JQuery) for the front-end rendering UI and handle user action in the client side.
In between, use aJax to get data from Zend backend.. most likely REST.
Anyone has suggestion about this kind of structure? I want to cut down the server load by that and also easier to manage code, plus better user experience.
Appreciate if anyone has good idea. :)
(POST few days later)
so, baseline PHP should be faster and use less data transfer (if code correctly) then Zend (or any) framework, right? Code reusablility is not a big concern here. :)
One thing many php developers fall victim of is sacrificing good architecture and sound principles for what they perceive as performance.
You may decide to cut corners in your code, but remember, "premature optimization is the root of all evil". So if you need to optimize early make sure that you're actually doing something useful.
The Zend libraries are engineered with best practice in mind, not necessarily performance. The rationale is that there are many ways to speed things up later without sacrificing code maintenance and readability (caching, load balancing, hardware, queue management, etc).
That been said, I don't think what you're looking for are statistics on ZF's performance, but rather advice on how to setup your application with it. Specifically, I'd advise you to create a dedicated, very light bootstrap for ajax requests. In ajax, you would normally only need some minimal prerequisites before dropping inside your controller. For the non ajax requests, set them up normally using the recommended architecture (bootstrap, front controller+plugins, controller+helpers, model+views+helpers).
My personal rule of thumb is that if I only am going to serve about 100 requests throughout the day, then there's very little reason to optimize anything. When the application starts feeling sluggish, if it generates enough revenue, maybe I can get a dedicated server, if not, there are always solutions such as apc, memcached, beanstalkd, etc.
Here's what you're looking for: PHP framework comparison benchmarks
Zend Framework vs raw PHP code tends to be close to a 1:500 requests per second ratio.
If you have a lot of time and not a lot of money, develop in raw PHP. If you have little time and enough money, develop in whatever is fastest without regard for performance...you can always add hardware later. If you fall in between the two, balance it as you see fit.
As much as I dislike it, CakePHP is faster to develop in than ZF, so it's great for time crunches. CodeIgniter is faster than either, but doesn't have as much built-in, so it's closer to the performance end of things without going to raw PHP.
There is only one thing to do first if you think that a ZF-based app is slow. Measure it. Various tools exist that will take the profiling output of Xdebug to show you which parts are slowing down the process, then you can make some moves towards optimising those parts (such as a lighter weight initialisation, and/or some caching). One good resource is the the Zend Framework book at survivethedeepend.com, "performance optimisation for ZF Apps".
In my opinion, benchmarks of frameworks are useless. They say something about an abstract situation, but performance is very situational. You should measure your application and optimise that. Yes, there's probably a limit to how far you can make your application go if you use lots of components from Zend Framework, but then there's also a limit for how fast your application can go before you need to drop PHP and write it in C. It's possible to make Zend Framework perform just fine on a high load site, but you have to put an effort in to it. Just like you have to if you don't use it.
I was looking for HTML/Text content caching for small-mid size site using php. I'll mostly save the dynamic navigation-menu for site, generated HTML report from DB etc. Primarily I am looking for session based caching (is it a bad idea?). It can also be file based.
Any existing solution is much appreciated. For example Zend Framework is well known for its loosely coupled components. So, Zend_Cache can be a candidate, but could not find session based caching adapter. Moreover, it is not completely independent component. Can anybody tell what are the classes that I need to take to use Zend_Cache?
Another option is PEAR's - Cache_Lite, whats your take on this?
Is there any other framework, from where I can easily separate the caching component and use it with less learning curve?
Thanks.
Memcached comes to mind, as a really lightweight and efficient solution.
But you can also cache content in simple files. The filesystem is usually fast, and handles read/write locks without problems. And there's no need for any fancy library to handle that...the functions filemtime, file_put_contents and file_get_contents are all you need.
Check if the cache has been written more than N secondes ago with filemtime()
If it's too old, generate the content and write it with file_put_contents()
If not, simply load it wit file_get_contents()
Edit: I'll add a link to that post I made a few months ago : Best Solution for caching. It's not completely on topic, but it might help you in your researchs :)
Session based caching is probably not a good idea. It's only appropriate in limited cases where you need to cache a specific result per-user (not for everyone).
APC is pretty widely deployed, so if you have access to it, I'd look into Zend_Cache with APC on the back end. If APC is not available, Zend_Cache with flat files on the back-end should be sufficient for small/medium type sites
JPCache is a decent lightweight caching library.
You can look at the caching in CakePHP. I doubt that you will be able to separate it from the frame work but it should help you to understand how to cache dynamic content.
Most of the php caching libraries are implemented using the output buffer control functions.
You can implement your own very simple caching the same way.
<?php
function callback($buffer)
{
// Code to store output in cache
}
if (/* Test cached copy is still valid */) {
/* Output cached copy to browser */
exit(0);
}
ob_start("callback");
?>
<html>...</html>
<?php
ob_end_flush();
?>
You can omit the ob_end_flush() if you like, since it will be triggered automatically at the end of the output.
The interesting thing to note is that this structure could be wrapped around smaller units than the page. For example you mention caching just the navigation menu. You'd need a bit more logic around the block to be cached, but the principle is the same.
I'm building a PHP site, but for now the only PHP I'm using is a half-dozen or so includes on certain pages. (I will probably use some database queries eventually.)
Are simple include() statements a concern for speed or scaling, as opposed to static HTML? What kinds of things tend to cause a site to bog down?
Certainly include() is slower than static pages. However, with modern systems you're not likely to see this as a bottleneck for a long time - if ever. The benefits of using includes to keep common parts of your site up to date outweigh the tiny performance hit, in my opinion (having different navigation on one page because you forgot to update it leads to a bad user experience, and thus bad feelings about your site/company/whatever).
Using caching will really not help either - caching code is going to be slower than just an include(). The only time caching will benefit you is if you're doing computationally-intensive calculations (very rare, on web pages), or grabbing data from a database.
Sounds like you are participating in a bit of premature optimization. If the application is not built, while performance concerns are good to be aware of, your primary concern should be getting the app written.
Includes are a fact of life. Don't worry about number, worry about keeping your code well organized (PEAR folder structure is a lovely thing, if you don't know what I'm talking about look at the structure of the Zend Framework class files).
Focus on getting the application written with a reasonable amount of abstraction. Group all of your DB calls into a class (or classes) so that you minimize code duplication (KISS principles and all) and when it comes time to refactor and optimize your queries they are centrally located. Also get started on some unit testing to prevent regression.
Once the application is up and running, don't ask us what is faster or better since it depends on each application what your bottleneck will be. It may turn out that even though you have lots of includes, your loops are eating up your time, or whatever. Use XDebug and profile your code once its up and running. Look for the segments of code that are eating up a disproportionate amount of time then refactor. If you focus too much now on the performance hit between include and include_once you'll end up chasing a ghost when those curl requests running in sync are eating your breakfast.
Though in the mean time, the best suggestions are look through the php.net manual and make sure if there's a built in function doing something you are trying to do, use it! PHP's C-based extensions will always be faster than any PHP code that you could write, and you'll be surprised how much of what you are trying to do is done already.
But again, I cannot stress this enough, premature optimization is BAD!!! Just get your application up off the ground with good levels of abstraction, profile it, then fix what actually is eating up your time rather than fixing what you think might eat up your time.
Strictly speaking, straight HTML will always serve faster than a server-side approach since the server doesn't have to do any interpretation of the code.
To answer the bigger question, there are a number of things that will cause your site to bog down; there's just no specific threshold for when your code is causing the problem vs. PHP. (keep in mind that many of Yahoo's sites are PHP-driven, so don't think that PHP can't scale).
One thing I've noticed is that the PHP-driven sites that are the slowest are the ones that include more than is necessary to display a specific page. OSCommerce (oscommerce.com) is one of the most popular PHP-driven shopping carts. It has a bad habit, however, of including all of their core functionality (just in case it's needed) on every single page. So even if you don't need to display an 'info box', the function is loaded.
On the other hand, there are many PHP frameworks out there (such as CakePHP, Symfony, and CodeIgniter) that take a 'load it as you need it' approach.
I would advise the following:
Don't include more functionality than you need for a specific page
Keep base functions separate (use an MVC approach when possible)
Use require_once instead of include if you think you'll have nested includes (e.g. page A includes file B which includes file C). This will avoid including the same file more than once. It will also stop the process if a file can't be found; thus helping your troubleshooting process ;)
Cache static pages as HTML if possible - to avoid having to reparse when things don't change
Nah includes are fine, nothing to worry about there.
You might want to think about tweaking your caching headers a bit at some point, but unless you're getting significant hits it should be no problem. Assuming this is all static data, you could even consider converting the whole site to static HTML (easiest way: write a script that grabs every page via the webserver and dumps it out in a matching dir structure)
Most web applications are limited by the speed of their database (or whatever their external storage is, but 9/10 times that'll be a database), the application code is rarely cause for concern, and it doesn't sound like you're doing anything you need to worry about yet.
Before you make any long-lasting decisions about how to structure the code for your site, I would recommend that you do some reading on the Model-View-Controller design pattern. While there are others this one appears to be gaining a great deal of ground in web development circles and certainly will be around for a while. You might want to take a look at some of the other design patterns suggested by Martin Fowler in his Patterns of Enterprise Application Architecture before making any final decisions about what sort of design will best fit your needs.
Depending on the size and scope of your project, you may want to go with a ready-made framework for PHP like Zend Framework or PHP On Trax or you may decide to build your own solution.
Specifically regarding the rendering of HTML content I would strongly recommend that you use some form of templating in order to keep your business logic separate from your display logic. I've found that this one simple rule in my development has saved me hours of work when one or the other needed to be changed. I've used http://www.smarty.net/">Smarty and I know that most of the frameworks out there either have a template system of their own or provide a plug-in architecture that allows you to use your own preferred method. As you look at possible solutions, I would recommend that you look for one that is capable of creating cached versions.
Lastly, if you're concerned about speed on the back-end then I would highly recommend that you look at ways to minimize your calls your back-end data store (whether it be a database or just system files). Try to avoid loading and rendering too much content (say a large report stored in a table that contains hundreds of records) all at once. If possible look for ways to make the user interface load smaller bits of data at a time.
And if you're specifically concerned about the actual load time of your html content and its CSS, Javascript or other dependencies I would recommend that you review these suggestions from the guys at Yahoo!.
To add on what JayTee mentioned - loading functionality when you need it. If you're not using any of the frameworks that do this automatically, you might want to look into the __autoload() functionality that was introduced in PHP5 - basically, your own logic can be invoked when you instantiate a particular class if it's not already loaded. This gives you a chance to include() a file that defines that class on-demand.
The biggest thing you can do to speed up your application is to use an Opcode cache, like APC. There's an excellent list and description available on Wikipedia.
As far as simple includes are concerned, be careful not to include too many files on each request as the disk I/O can cause your application not to scale well. A few dozen includes should be fine, but it's generally a good idea to package your most commonly included files into a single script so you only have one include. The cost in memory of having a few classes here and there you don't need loaded will be better than the cost of disk I/O for including hundreds of smaller files.