Since I was relatively new to PHP before I started Moodle development (though with quite a lot of experience in other systems), I realised that I still don't have a solid grasp of performance issues re PHP in terms of which operations are slow and which are fast. Of course I have an intuition but it's one borne of other systems - is it still accurate?
Just for fun and because I was bored writing spec documents, I wrote a little script to check. Maybe this will also be useful background for other developers new to PHP.
Here are the results for our developer system (this is obviously using a machine and database that are less powerful than those in our real system):
In one second you can do...
- 64000 function calls
- 10300 16KB files read from disk (cache)
- 4800 regular expression replaces over 1KB of text
- 4000 16KB files written to disk (cache)
- 570 get_record calls on the course table
- 230 insert_record calls on the course table
- 30 update_record calls on the course table
The first thing I got slightly wrong was the CPU issue. 64,000 really isn't that many function calls for a whole second, and the regular expressions are kind of slow (it's not a complicated regular expression).
Disk access is comparably pretty quick, not surprisingly since in this test it's coming entirely from the cache. So if I really wanted to do 1KB regular expression replaces on something, and I needed to repeat the results frequently, it would be worth saving it as a file.
Database access, as expected, is dog slow (looking just at get_record for the moment). So not worth caching anything in the database unless the thing you're caching itself requires multiple database accesses to calculate, or a lot of file access or CPU time.
The last point I wouldn't necessarily have expected is update_record. Huh? Is that just our system? Why is it so appallingly slow compared to insert? Is there a mistake in my test? I could update records quicker with a pencil.
I don't know the specs of our development system, but this is using a Postgres 8.1 database which may have an effect on that update_record result. (By the way, I tried bracketing everything in begin_sql and commit_sql, because some suggested that makes a large performance difference on Postgres; but in this case it didn't seem to.)
Anyhow, maybe I'll run this on the real servers in a few weeks when there'll be a chance. If anyone else wants to run it, feel free - I've attached the script here. You need to put the script somewhere within your Moodle 1.7 install [may work in 1.6, don't know], and edit the file so that the require_once for config.php points to the right place.
If you try it, only run this on a test install. In particular the script should not be accessible by the public as it provides a possible route for a DoS attack, and also it modifies the real course table $CFG->prefix_course (hopefully undoing everything later, but still, maybe I screwed up and you lose your course table, does that sound like fun? didn't think so).