Archive

Posts Tagged ‘performance’

PHP That Just Works

September 18th, 2009
Comments Off

I’m not one of those developers that likes to waste time setting up my dev environment. If I have a project to complete, I should be coding, not messing with config files, compiling Apache or messing with PHP to load that extension I just found out I needed. I like messing with my machine but not with an impending deadline.

With all this in mind, I’ve tried to simplify my entire dev environment over the years… not from a perspective of using simple tools and sticking to basics, but instead from a perspective of optimizing my workflow and keeping my development moving. In the middle of a project, I feel that systems admin focus should be on tweaking the production machines, rather than screwing around with my local dev box.

Zend Server CE Control PanelAlways looking for ways to make development easier, I decided to give the Zend Server CE (Community Edition) a try. The idea is that it installs your PHP, Apache, MySQL (with PHPMyAdmin) and a great management console that allows you to install extensions with just a click. You can still customize our Apache conf and other things, but it works well out of the box (I’m on a Mac). While you can run it along side another Apache installation, I tweaked it to run on port 80 and handle multiple virtual hosts. While this may not be ideal for all teams, it can allow everyone to have the same environment without having to mess with poorly updated all-in-one dev environments.

One of the reasons this excites me, being on a Mac, is that every time in the past that I’ve updated my Mac OS, the install kills something on my system causing my development environment to go all wonky. Then I have to spend precious work time to fix it. The Zend Server CE install keeps everything nice and tidy and, to my knowledge, doesn’t rely on other stuff outside of the install to function (unless you are setting host entries in your hosts file, /etc/hosts on a Mac).

This, oh so sweet, environment gets a little better. While I still have a variety of development tools at my disposal, my main IDE has become Zend Studio (Eclipse). I know, I know… there are a lot of purists out there that say it’s too heavy, or sluggish, or isn’t simplistic enough. There are occasional bugs or things that annoy me, but at the end of the day it is integrated enough that it lets me get my work done. That’s the whole point of an IDE. It also integrates with Flex Builder plugin which is a plus for me.

Development, PHP, Reviews , , , , , ,

PHP Optimization

February 12th, 2009
Comments Off

Many developers don’t really put much thought into code optimization. Frankly, their applications don’t see enough traffic for optimization to be much of an issue. However, regardless of your application’s actual needs and whether or not you are having speed issues, there are some good habits that you can develop that will either help you in a bind or just ensure that all of your applications are finely tuned machines.

Optimization can be frustrating at times. I am quite familiar with server systems, however, I do not consider myself a full-fledged systems admin. The more I learn, the more I realize I don’t know. I do know that finding the right balance between server and code optimization takes skill. Too much customization in either direction can make the code or server difficult to manage. Sometimes, throwing more hardware at the problem can do the trick, but this is usually just temporary as the problem usually multiplies itself by the number of servers your application is running on. Inversely, good optimization improves performance across all the servers the application is running on.

Typically, I figure that if a particular change makes something overly difficult to manage, then it probably is not worth doing, because there are usually other people involved and there is too much room for mistakes. I will sometimes break this rule for my own personal stuff since I am the only one involved. You need to decide at what point it becomes to difficult. Good documentation goes a long way.

Here are some of the things (using PHP as the example) that I will often do to optimize things at the software level, without going too far.

  • It’s good practice to use literal strings wherever possible. Using the doublequotes tells the parser to expect potential interpretable values in the string, slowing down processing just a bit. This can add up with HTML intensive applications.
  • Keep code files from getting too large. If two chunks of code are rarely used together split them into separate files so that PHP doesn’t have to load more code than necessary.
  • Keep file inclusions to a minimum. Inclusions require additional disk reads and adds more time to processing. Don’t go overboard and sacrifice code organization in the process… includes can be your friend. If the include makes sense, do it. MVC development often ignores this because of the nature of the methodology, but it is still a good practice to keep in mind whether using MVC or not.
  • Try to convert any uses of division to multiplication. Division eats up processing, especially if iterated several times. Example: instead of $var / 10 do $var * .1
  • Utilize break or continue to control code flow in loops, etc… If you review enough of your code, there are probably some areas where you are using a for() or foreach() that are running beyond their necessary iterations. In other words, you run the loop to accomplish a certain task or value, but the loop continues to run through all possible interations, even after the task or value is complete. Either find ways to use while() or use break or continue where possible.
  • Sometime a caching application can help ease unnecessary processing. TurkMM or APC can dramatically improve PHP processing speeds by keeping realtime code compiling to a minimum.
  • Other types of caching can be done using Memcached or other similar code. This type of caching can cache files, database results, large data objects, etc… If there is any data that requires processing that doesn’t change much between pages or between users, this type of caching can drastically speed up response times. This is not only helpful for bypassing unnecessary processing, but it can also limit your application’s need to hit the database. Memcached can be used on many levels of the application to reduce processing and web service request overhead. For example, a list of users may not change very often, so there isn’t a need to retrieve a fresh list upon every request. You could cache the list for 2 hours, for instance, and your application would only have to query the database for the list once every 2 hours, instead of every page load.
  • Only use SSL where necessary. SSL encryption slows the response of your application.
  • A browser will hold on to the connection with the webserver as long as it is waiting to receive data, hence requiring the webserver, in this case Apache, to standby until everything is processed and ready to send. In some cases, your data may not require the user to review anything afterward, so it may be a good thing to consider forking your code into multiple threads. This can be tricky, but if done properly, Apache will respond to the user faster, leaving connections open for other users and allowing the code to finish in it’s own time. There are also functions in PHP that allow you to check if the user’s browser is still responding to the connection and close the connection if needed.
  • When a database is involved, use good SQL and data handling processes. I won’t go into a lot of SQL specifics here, but the following are things to consider:
    • Only request the data you need from the database. The more data that is requested, the more that has to be sent across the wire and get parsed by the application.
    • When your application is done processing a large data set, it should release the result set to free up memory for other operations. If only parts of the data are needed for processing later in the request, those parts of the data can be copied to another data object while the original object is cleared. Most applications don’t work with large enough data sets to have this concern, but when you do, you’ll find that automatic garbage collection won’t be enough.
    • Most modern databases will allow you to combine multiple operations into a single SQL request. Taking advantage of this can GREATLY minimize your application’s overhead of going back and forth to the database. For example, you can combine multiple SELECT queries using UNIONs. You can do conditional INSERTs when you might normally do a SELECT, check the logic in your code, then do an INSERT. Take advantage of subqueries. Also, in some cases it can be beneficial to do a few large queries early in your application and avoid the several smaller ones that might be required later.
    • Take advantage of query caching and preparing if your database and code support this functionality.
    • When possible, have the database be on the same machine as the application. This introduces some scalability challenges (to be discussed at another time), but can be worth the effort, even with large, distributed applications. This will keep your code-to-database processing times VERY fast.
  • Keep what your store in sessions to a minimum. You can also use Memcached as a custom session handler between servers to replace database sessions across multiple servers, for improved performance.
  • When possible, “minify” your JavaScript, CSS and HTML. Keep the output to a minimum and write your code so that the browser will take optimal advantage of cached CSS, JavaScript and HTML
  • PHP is an interpreted scripting language. When it comes down to it, it can only move so fast. For larger applications that do a lot of processing, it can greatly decrease the system load to offload major processing to a program written using a compiled language such as C, C++, or yes, even Java. You can build an RPC interface to the compiled app using JSON, SOAP or XMLRPC. Service communication may take some overhead, but the compiled app will more than make up for it. Using this method allows you to keep your interface code flexible using PHP while gradually putting any labor-intensive operations on to something more suitable.

Doing any or all of these things will benefit your applications greatly and still keep your code manageable. This doesn’t address all of the innovative things you can do on the UI and client-side of an application to improve performance. Of course there is always more you can do, but this should get you started.

Development, PHP , , , ,

Script Timing in PHP

August 4th, 2008
Comments Off

Knowing how long something takes to process is very important. However, hand-rolling a timing solution every time you need one can be frustrating. This little class is a very lightweight solution that allows you to to simply start a timer, then capture elapsed time at various points in your program.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
 
class Script_Timer
{
    /**
     * Start timer
     *
     * @return BOOLEAN
    */

    public static function start()
    {
        $success = false;
        try
        {
            if(!self::started())
            {
                define('TIMER_START_TIME', microtime());
            }

            $success = true;
        }
        catch(Exception $e)
        {
            //
        }

        return $success;
    }

    /**
     * Check if timer is started
     *
     * @return  BOOLEAN status of timer
     */

    public static function started()
    {
        $started = false;

        if(defined('TIMER_START_TIME'))
        {
            $started = true;
        }

        return $started;
    }

    /**
     * Get timestamp of start time
     *
     * @return STRING   microtime of time start
     */

    public static function get_Start()
    {
        $start_time = null;

        if(self::started())
        {
            $start_time = TIMER_START_TIME;
        }

        return $start_time;
    }

    /**
     * Get number of seconds since script start
     *
     * @param INTEGER   $decimals   number of decimals to capture
     *
     * @return NUMBER   seconds since script start
    */

    public static function get($decimals=2)
    {
        // format start time
        $start_time = explode(' ', TIMER_START_TIME);
        $start_time = $start_time[1] + $start_time[0];
        // get and format end time
        $end_time = explode(' ', microtime());
        $end_time = $end_time[1] + $end_time[0];

        return number_format($end_time - $start_time, $decimals);
    }

    /**
     * Get number of seconds from given count
     *
     * @param NUMBER    $prev_seconds   number of seconds from a previous get() value
     * @param INTEGER   $decimals       number of decimals to capture
     *
     * @return NUMBER   seconds since script start
     */

    public static function diff($prev_seconds, $decimals=2)
    {
        $current_time = self::get(4);

        $diff_seconds = $current_time - $prev_seconds;

        return number_format($diff_seconds, $decimals);
    }
}

The example below shows how the class is used statically so that the scope of an instantiated timer object doesn’t become a problem.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// start timer  Script_Timer::start();

// do some processing.....  

// Then when you are ready to get current time since start, run:

$new_time_1 = Script_Timer::get();

// do some processing.....

$new_time_2 = Script_Timer::get();

// You can also get the difference from another time until current:

// do some processing.....

$time_diff = Script::diff($new_time_2);

You can even set the timed values to an arrar or session, so that you can keep them together and run evalutions and comparisons on them later.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// start timer
Script_Timer::start();

$_SESSION['timer'] = array();

// initiate first time capture

$_SESSION['timer']['start'] = Script_Timer::get();

// do some processing.....

$_SESSION['timer']['point_a'] = Script_Timer::get();   

// do some processing.....

$_SESSION['timer']['point_b'] = Script_Timer::get();

// do some processing.....

$_SESSION['timer']['point_c'] = Script_Timer::get();

$point_c_processing_time = $_SESSION['timer']['point_c'] - $_SESSION['timer']['point_b'];

Using the time statically, as shown above, can be great for an entire application, however, sometimes you just want to implement a timer within a specific class. In this case, you might consider using the the timer for internal class use only.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class My_Class
{
    public function __construct()
    {
        Script_Timer::start();
    }

    public function my_Method()
    {
        // do something
 
       echo Script_Timer::get() . ' seconds';
    }
}

Development, PHP, Uncategorized , , ,



Sponsored Links



agile ajax black hat Cake PHP centering clifford stoll css cuckoo's egg energy energy drinks espionage flash Flex hacker jquery modular MVC objects optimization performance PHP script timer smarty smarty templates stylesheet up-time uptime variable scope web 2.0 Zend Framework