Simple Machines Community Forum

Simple Machines => SMF Developers' Blog => Topic started by: Thantos on June 03, 2007, 03:00:23 PM

Title: PHP String Replacement Speed Comparison
Post by: Thantos on June 03, 2007, 03:00:23 PM
Recently I redid a test to determine the speed of various string replacement methods in PHP.  A little over a year ago, Grudge did a test of the same nature.  Based off of his results some decisions were made on how to proceed.  My goal was to verify his test using some of the formats we decided to go with.

String Replacement Methods
I looked at the four main methods of string replacement used in SMF:

sprintf
http://www.php.net/manual/en/function.sprintf.php
sprintf operates almost exactly like the *printf functions in C.  Main difference is that PHP supports argument numbering.  We are slowly moving towards having all of our sprintfs using argument numbering.

preg_replace
http://www.php.net/manual/en/function.preg-replace.php
This function uses Perl regular expressions (http://en.wikipedia.org/wiki/Regular_expression) to find and replace substrings.  Regular Expressions can be extremely powerful and at the same time extremely hard to understand.

strtr
http://www.php.net/manual/en/function.strtr.php
strtr is used for translating one substring to another.  The way SMF has been using it is with the string strtr ( string $str, array $replace_pairs ) format.  In this format, the longest substrings are found first and the function will try to avoid doing a replacement on something it has already worked on.

str_replace
http://www.php.net/manual/en/function.str-replace.php
str_replace finds substrings in the order they are given and replaces them with the corresponding substring.

Understanding the difference between strtr and str_replace
strtr and str_replace both seem to operate the same way.  However, due to strtr's unique properties the results can be very different.

Example:  PHP: Hypertext Preprocessor
Replacements:
   PHP => PHP: Hypertext Preprocessor
   PHP: Hypertext Preprocessor => PHP
strtr:      PHP
str_replace:   PHP: Hypertext Preprocessor

To understand why lets examine the behavior:

strtr
First strtr will sort the parameters by length of the substring with the longest first.  So we get
Replacements:
   PHP: Hypertext Preprocessor => PHP
   PHP => PHP: Hypertext Preprocessor

So it finds " PHP: Hypertext Preprocessor" in our example and replaces it with "PHP" so now our example contains "PHP".  Next it searches for "PHP" in "PHP" but the only instance it found is one it has already worked on so it doesn't do the replacement.  So it is done.

str_replace
First str_replace finds finds "PHP" in "PHP: Hypertext Preprocessor" and replaces it with "PHP: Hypertext Preprocessor" which gives us "PHP: Hypertext Preprocessor: Hypertext Preprocessor".  Next it finds "PHP: Hypertext Preprocessor" in "PHP: Hypertext Preprocessor: Hypertext Preprocessor" which gives us "PHP: Hypertext Preprocessor" since it doesn't care that it already changed that part of the string.

Testing Procedure
A test script was written—attached to this post—and uploaded to the Simple Machines website.  The script was accessed and the results recorded throughout the day. The results will be more realistic on a production server then on a test server, due to the server load on production sites.  The times were varied in order to account for server load changes.

For each method the time was stored before and after the method was ran 100,000 times.  The difference in time was then calculated and displayed.

The str_replace method was ran using two different methods.  For the first method the parameters were put into arrays prior to starting the test.  For the second method the parameter arrays were created in every iteration.  This type of setup is typical and adds to the execution time.

Test Results
In the following table I give all the results of the each test.  The times for each method are in seconds.


   
   
   
   
   
   
   
Time
sprintf
preg_replace
strtr
str_replace #1
str_replace #2
08:00:00 AM
1.1334
2.0955
48.1423
1.2109
1.4819
08:40:00 AM
1.0436
2.0326
64.3492
1.7948
2.2337
11:30:00 AM
1.1841
2.5524
62.0114
1.5931
1.9200
02:00:00 PM
0.9783
2.4832
52.6339
1.3966
1.4845
03:00:00 PM
1.0463
2.6164
52.7829
1.1828
1.4981
Average
1.0771
2.3560
55.9839
1.4357
1.7237

Calculated Results
The following table gives the speed of each method as a multiple of the time it took sprintf.

Method
Times Slower
preg_replace
2.19
strtr
51.97
str_replace #1
1.33
str_replace #2
1.6
Another method of comparing speeds is to look at the number of executions each method did each second.

Method
Speed
sprintf
92838
preg_replace
42444
strtr
1786
str_replace #1
69654
str_replace #2
58016

Analysis of results
The sprintf method is the fastest in string replacement; however, str_replace method #1 was only slighty slower.

While the test were done over 100,000 iterations the actual number of replacements done during script execution shouldn't exceed more then a few hundred iterations.  As such, even strtr isn't too slow to be used.

It is also important to note that the preg_replace expression was very simplistic.  For more complex expressions the function will take longer to execute as pattern matching is not a simple problem.

My Recommendations
Whenever you are concerned with pure speed you should go with *printf.  However, when you are concerned about human readability str_replace provides a good alternative.  I recommend that you avoid using strtr unless you need its unique properties.  At the same time don't invest a lot of time trying to rip it out.



I hope you all gained some useful information for this.
Title: Re: PHP String Replacement Speed Comparison
Post by: Joshua Dickerson on June 03, 2007, 11:47:58 PM
I remember doing a test a while back and receiving very different results. strtr() was the fastest out of the group. I might try your script out a little later and post my results.

I think it is important to note the PHP version, the webserver & version, the OS, the hardware, the load, and some specs relating to the software you are running. Since this is a benchmark of a core PHP function, I think the minimum that should be supplied is PHP version and the load.

Neverminding that stuff, nice to see some more benchmarks :). I loves me some benchmarks.
Title: Re: PHP String Replacement Speed Comparison
Post by: ディン1031 on June 05, 2007, 02:16:41 AM
Intressting, i new that strtr is slow... but so slow. I thought it depend on the array that you use for this.

Okay i prefere str_replace but i never thought that sprintf is so fast.

Bye
DIN1031
Title: Re: PHP String Replacement Speed Comparison
Post by: Thantos on June 05, 2007, 02:45:46 AM
Quotestrtr() was the fastest out of the group.
TBH I find that hard to believe.  strtr has much more work to do then str_replace does.  I can not see any reasonable implementation of str_replace being slower then strtr for the same set of replacements.  Well actually I could see one set of strings that it could be faster one, namely take a larger number of N substrings but the longest substring is the string S, then I could see strtr stopping at the first one but str_replace would still process the rest.  However that isn't really comparing speed and it plays off of strtr's properties.

Quote from: ディン1031 on June 05, 2007, 02:16:41 AM
Intressting, i new that strtr is slow... but so slow. I thought it depend on the array that you use for this.

Okay i prefere str_replace but i never thought that sprintf is so fast.

Bye
DIN1031
When Grudge ran his test he used '%1$s' type of substrings for strtr and str_replace and in his results the strtr was much lower (though still slower then the rest).  I do suspect that the string lengths do play a role in the exact speed; but, for a typical set of strings I think the relationship between speeds will be about the same.

A good implementation of *printf only needs to scan the string once.  For str_replace I wouldn't be surprised if it scaned the string once for each substring.
Title: Re: PHP String Replacement Speed Comparison
Post by: Grudge on June 07, 2007, 05:23:31 PM
Can you remember what my conclusions were out of interest?
Title: Re: PHP String Replacement Speed Comparison
Post by: Thantos on June 07, 2007, 05:36:03 PM
Almost the same.  Your strtr time weren't as bad but still the worse of them all.  IIRC you only tested the first version of str_replace.  Our tests had the same relationship between the functions.
Title: Re: PHP String Replacement Speed Comparison
Post by: Joshua Dickerson on June 08, 2007, 01:43:29 PM
Quote from: groundup on June 03, 2007, 11:47:58 PM
I remember doing a test a while back and receiving very different results. strtr() was the fastest out of the group. I might try your script out a little later and post my results.

I think it is important to note the PHP version, the webserver & version, the OS, the hardware, the load, and some specs relating to the software you are running. Since this is a benchmark of a core PHP function, I think the minimum that should be supplied is PHP version and the load.

Neverminding that stuff, nice to see some more benchmarks :). I loves me some benchmarks.
Was I drunk when I posted this? I must have been retarded. Oh well, stupid me.
Title: Re: PHP String Replacement Speed Comparison
Post by: KGIII on June 08, 2007, 02:17:11 PM
I couldn't resist. Here are the results in case anyone should care.

sprintf: 1.38384985924 seconds
preg_replace: 3.27423620224 seconds
strtr: 40.9357118607 seconds
str_replace #1: 1.49082899094 seconds
str_replace #2: 1.94922995567 seconds
Title: Re: PHP String Replacement Speed Comparison
Post by: Daniel15 on June 09, 2007, 08:51:05 AM
Heh, I tried this on my slow little test server:
Quote
sprintf: 2.92035603523 seconds
preg_replace: 5.3017771244 seconds
strtr: 145.762818813 seconds
str_replace #1: 7.66827106476 seconds
str_replace #2: 8.1126139164 seconds

Quotethink it is important to note the PHP version, the webserver & version, the OS, the hardware, the load, and some specs relating to the software you are running.
Mine was on a Pentium III 650 MHz, Debian Testing, run via CLI.
If you're interested:
Quote

daniel@server:/tmp$ uname -a
Linux server.daniel15.com 2.6.18-4-vserver-686 #1 SMP Mon Mar 26 19:55:22 UTC 2007 i686 GNU/Linux

daniel@server:/tmp$ php -v
PHP 5.2.0-10+lenny1 (cli) (built: May 26 2007 08:23:53)
Copyright (c) 1997-2006 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2006 Zend Technologies
    with XCache v1.2.0, Copyright (c) 2005-2006, by mOo

daniel@server:/tmp$ uptime
22:41:54 up 17 days,  4:04,  1 user,  load average: 0.01, 0.02, 0.00

daniel@server:/tmp$ cat /proc/cpuinfo
processor       : 0
vendor_id       : GenuineIntel
cpu family      : 6
model           : 8
model name      : Pentium III (Coppermine)
stepping        : 3
cpu MHz         : 651.504
cache size      : 256 KB
fdiv_bug        : no
hlt_bug         : no
f00f_bug        : no
coma_bug        : no
fpu             : yes
fpu_exception   : yes
cpuid level     : 2
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 sep mtrr pge mca cmov pat pse36 mmx fxsr sse up
bogomips        : 1304.01

daniel@server:/tmp$ cat /proc/meminfo
MemTotal:       516788 kB
MemFree:         15272 kB
Buffers:         78256 kB
Cached:         151132 kB
SwapCached:          0 kB
Active:         342692 kB
Inactive:       101892 kB
HighTotal:           0 kB
HighFree:            0 kB
LowTotal:       516788 kB
LowFree:         15272 kB
SwapTotal:      979956 kB
SwapFree:       979816 kB
Dirty:             244 kB
Writeback:           0 kB
AnonPages:      215192 kB
Mapped:          47692 kB
Slab:            49392 kB
PageTables:       2572 kB
NFS_Unstable:        0 kB
Bounce:              0 kB
CommitLimit:   1238348 kB
Committed_AS:   518804 kB
VmallocTotal:   507896 kB
VmallocUsed:      3764 kB
VmallocChunk:   504084 kB



server:/tmp# vps aux
USER       PID CONTEXT             %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1     0 MAIN           0.0  0.1   1944   640 ?        Ss   May23   0:02 init [2]
root         2     0 MAIN           0.0  0.0      0     0 ?        S    May23   0:00 [migration/0]
root         3     0 MAIN           0.0  0.0      0     0 ?        SN   May23   0:00 [ksoftirqd/0]
root         4     0 MAIN           0.0  0.0      0     0 ?        S<   May23   0:00 [events/0]
root         5     0 MAIN           0.0  0.0      0     0 ?        S<   May23   0:00 [khelper]
root         6     0 MAIN           0.0  0.0      0     0 ?        S<   May23   0:00 [kthread]
root         9     0 MAIN           0.0  0.0      0     0 ?        S<   May23   0:00 [kblockd/0]
root        10     0 MAIN           0.0  0.0      0     0 ?        S<   May23   0:00 [kacpid]
root        60     0 MAIN           0.0  0.0      0     0 ?        S<   May23   0:00 [kseriod]
root        95     0 MAIN           0.0  0.0      0     0 ?        S    May23   0:02 [pdflush]
root        96     0 MAIN           0.0  0.0      0     0 ?        S<   May23   0:22 [kswapd0]
root        97     0 MAIN           0.0  0.0      0     0 ?        S<   May23   0:00 [aio/0]
root       604     0 MAIN           0.0  0.0      0     0 ?        S<   May23   0:00 [khubd]
root       837     0 MAIN           0.0  0.0      0     0 ?        S<   May23   0:02 [kjournald]
root       999     0 MAIN           0.0  0.1   2176   604 ?        S<s  May23   0:00 udevd --daemon
root      1307     0 MAIN           0.0  0.0      0     0 ?        S<   May23   0:00 [kpsmoused]
root      1315     0 MAIN           0.0  0.0      0     0 ?        S<   May23   0:00 [kgameportd]
root      1513     0 MAIN           0.0  0.0      0     0 ?        S<   May23   0:00 [kmirrord]
root      1544     0 MAIN           0.0  0.0      0     0 ?        S<   May23   0:00 [kjournald]
root      1546     0 MAIN           0.0  0.0      0     0 ?        S<   May23   0:00 [kjournald]
root      1548     0 MAIN           0.0  0.0      0     0 ?        S<   May23   0:07 [kjournald]
root      1550     0 MAIN           0.0  0.0      0     0 ?        S<   May23   1:00 [kjournald]
root      4455     0 MAIN           0.0  0.1   1624   568 ?        Ss   May23   0:05 /sbin/syslogd
root      4471     0 MAIN           0.0  0.0   1576   388 ?        Ss   May23   0:00 /sbin/klogd -x
bind      4487     0 MAIN           0.0  0.7  31068  3784 ?        Ssl  May23   0:20 /usr/sbin/named -u bind
root      4543     0 MAIN           0.0  0.2   2664  1332 ?        S    May23   0:00 /bin/sh /usr/bin/mysqld_safe
mysql     4582     0 MAIN           0.0  5.4 127688 28420 ?        Sl   May23   2:34 /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --user=mysql --pid-file=/var/run/mysqld/mysqld.pid --skip-external-locking --port=3306 --socket=/var/run/mysqld/mysqld.sock
root      4584     0 MAIN           0.0  0.0   1560   508 ?        S    May23   0:00 logger -p daemon.err -t mysqld_safe -i -t mysqld
root      4707     0 MAIN           0.0  0.1   1576   568 ?        Ss   May23   0:00 /usr/sbin/acpid -c /etc/acpi/events -s /var/run/acpid.socket
approx    4715     0 MAIN           0.0  0.2   3696  1460 ?        S    May23   0:00 /usr/sbin/approx
102       4770     0 MAIN           0.0  0.1   5272   988 ?        Ss   May23   0:00 /usr/sbin/exim4 -bd -q30m
root      4813     0 MAIN           0.0  0.1   1712   572 ?        S    May23   0:00 /usr/sbin/hddtemp -d -l 127.0.0.1 -p 7634 -s | /dev/hda
root      4842     0 MAIN           0.0  0.2   4932  1080 ?        Ss   May23   0:00 /usr/sbin/sshd
root      4845     0 MAIN           0.0  0.0   1764   396 ?        Ss   May23   0:01 /usr/sbin/ulogd -d
root      5112 49153 gforge01       0.0  0.1   1632   624 ?        Ss   May23   0:03 /sbin/syslogd
root      5113 49152 gforge01-web   0.0  0.1   1628   564 ?        Ss   May23   0:01 /sbin/syslogd
daemon    5129 49152 gforge01-web   0.0  0.0   1688   352 ?        Ss   May23   0:00 /sbin/portmap
root      5157 49152 gforge01-web   0.0  0.1   2200   884 ?        Ss   May23   0:00 /usr/sbin/cron
mysql     5168 49153 gforge01       0.0  0.7  19356  3688 ?        S    May23   0:16 /usr/lib/postgresql/8.1/bin/postmaster -D /var/lib/postgresql/8.1/main -c config_file=/etc/postgresql/8.1/main/postgresql.conf
mysql     5200 49153 gforge01       0.0  1.9  19488  9880 ?        S    May23   0:00 postgres: writer process
mysql     5201 49153 gforge01       0.0  0.3  10136  1988 ?        S    May23   0:44 postgres: stats buffer process
mysql     5202 49153 gforge01       0.0  0.2   9308  1264 ?        S    May23   0:26 postgres: stats collector process
sshd      5259 49153 gforge01       0.0  0.1   5308   996 ?        Ss   May23   0:00 /usr/sbin/exim4 -bd -q30m
list      5268 49153 gforge01       0.0  0.8   8708  4532 ?        Ss   May23   0:00 /usr/bin/python /usr/lib/mailman/bin/mailmanctl -s -q start
root      5278 49153 gforge01       0.0  0.2   4932  1112 ?        Ss   May23   0:00 /usr/sbin/sshd
list      5279 49153 gforge01       0.0  1.2   9216  6496 ?        S    May23   0:01 /usr/bin/python /var/lib/mailman/bin/qrunner --runner=ArchRunner:0:1 -s
list      5280 49153 gforge01       0.0  1.1   8344  5704 ?        S    May23   0:00 /usr/bin/python /var/lib/mailman/bin/qrunner --runner=BounceRunner:0:1 -s
list      5281 49153 gforge01       0.0  1.1   8372  5708 ?        S    May23   0:00 /usr/bin/python /var/lib/mailman/bin/qrunner --runner=CommandRunner:0:1 -s
list      5282 49153 gforge01       0.0  1.1   8688  6004 ?        S    May23   0:00 /usr/bin/python /var/lib/mailman/bin/qrunner --runner=IncomingRunner:0:1 -s
list      5283 49153 gforge01       0.0  1.1   8612  5740 ?        S    May23   0:00 /usr/bin/python /var/lib/mailman/bin/qrunner --runner=NewsRunner:0:1 -s
list      5284 49153 gforge01       0.0  1.1   8596  5856 ?        S    May23   0:00 /usr/bin/python /var/lib/mailman/bin/qrunner --runner=OutgoingRunner:0:1 -s
list      5285 49153 gforge01       0.0  1.1   8364  5700 ?        S    May23   0:00 /usr/bin/python /var/lib/mailman/bin/qrunner --runner=VirginRunner:0:1 -s
list      5286 49153 gforge01       0.0  1.1   8372  5700 ?        S    May23   0:00 /usr/bin/python /var/lib/mailman/bin/qrunner --runner=RetryRunner:0:1 -s
root      5319 49153 gforge01       0.0  0.1   2196   892 ?        Ss   May23   0:00 /usr/sbin/cron
root      5401     0 MAIN           0.0  0.1   4636   680 ?        Ss   May23   0:00 /usr/sbin/squid -D -sYC
proxy     5411     0 MAIN           0.0  3.3  19452 17492 ?        S    May23   6:26 (squid) -D -sYC
root      5413     0 MAIN           0.0  0.1   2192   884 ?        Ss   May23   0:00 /usr/sbin/cron
proxy     5422     0 MAIN           0.0  0.0   1420   288 ?        Ss   May23   0:01 (unlinkd)
root      5488     0 MAIN           0.0  1.1   9884  6088 ?        Ss   May23   0:00 /usr/bin/perl /usr/share/webmin/miniserv.pl /etc/webmin/miniserv.conf
root      5500     0 MAIN           0.0  0.0   1576   468 tty1     Ss+  May23   0:00 /sbin/getty 38400 tty1
root      5501     0 MAIN           0.0  0.0   1572   464 tty2     Ss+  May23   0:00 /sbin/getty 38400 tty2
root      5502     0 MAIN           0.0  0.0   1572   464 tty3     Ss+  May23   0:00 /sbin/getty 38400 tty3
root      5503     0 MAIN           0.0  0.0   1576   468 tty4     Ss+  May23   0:00 /sbin/getty 38400 tty4
root      5504     0 MAIN           0.0  0.0   1572   464 tty5     Ss+  May23   0:00 /sbin/getty 38400 tty5
root      5507     0 MAIN           0.0  0.0   1576   464 tty6     Ss+  May23   0:00 /sbin/getty 38400 tty6
root      5642 49154 public01       0.0  0.1   1632   624 ?        Ss   May23   0:00 /sbin/syslogd
root      5668 49154 public01       0.0  0.1   2200   884 ?        Ss   May23   0:00 /usr/sbin/cron
root      5727     0 MAIN           0.0  0.2   3956  1096 ?        Ss   May23   0:00 SCREEN
root      5728     0 MAIN           0.0  0.3   3964  1664 pts/1    Ss   May23   0:00 /bin/bash
root      5729     0 MAIN           0.0  0.3   3940  1560 pts/1    S+   May23   0:00 /bin/bash /usr/sbin/chbind --silent --secure --ip 10.1.1.7/12 /usr/lib/util-vserver/exec-ulimit /etc/vservers/public01/ulimits /usr/sbin/vnamespace --enter 49154 -- /usr/sbin/vcontext --silent --migrate --chroot --xid 49154 --uid 0 --vlogin -- /bin/bash -login
root      5752 49154 public01       0.0  0.0    120    40 pts/1    S+   May23   0:00 login
root      5753 49154 public01       0.0  0.3   4000  1692 pts/2    Ss   May23   0:00 /bin/bash -login
daniel    5758 49154 public01       0.0  0.2   3720  1064 pts/2    S    May23   0:00 su - daniel
daniel    5759 49154 public01       0.0  0.5   3992  2624 pts/2    S    May23   0:00 -su
daniel    5777 49154 public01       0.0  2.7  35132 14048 pts/2    S+   May23  20:42 /usr/bin/python /usr/bin/supybot FrihBot.conf
root     18770     0 MAIN           0.0  0.0      0     0 ?        S    May27   0:05 [pdflush]
root     12530     0 MAIN           0.0  0.1   2752   888 ?        Ss   Jun01   0:05 /usr/sbin/pppd call dsl-provider
root     13570     0 MAIN           0.0  0.2   6888  1440 ?        Ss   Jun01   0:00 /usr/sbin/nmbd -D
root     13572     0 MAIN           0.0  0.5  10068  2652 ?        Ss   Jun01   0:00 /usr/sbin/smbd -D
root     13577     0 MAIN           0.0  0.2  10068  1044 ?        S    Jun01   0:00 /usr/sbin/smbd -D
root     27739 49153 gforge01       0.0  1.4  19892  7444 ?        Ss   Jun03   0:01 /usr/sbin/apache2 -k start
root     28507 49152 gforge01-web   0.0  0.5   9568  2608 ?        Ss   Jun03   0:00 /usr/sbin/apache2 -k start
root     29574     0 MAIN           0.0  1.6  41436  8596 ?        Ss   Jun03   0:01 /usr/sbin/apache2 -k start
www-data  4919 49152 gforge01-web   0.0  0.8  11592  4560 ?        S    Jun07   0:12 /usr/sbin/apache2 -k start
www-data  6337 49152 gforge01-web   0.0  0.9  11872  4820 ?        S    Jun07   0:18 /usr/sbin/apache2 -k start
www-data  6488 49152 gforge01-web   0.0  1.0  12556  5500 ?        S    Jun07   0:17 /usr/sbin/apache2 -k start
www-data 28787 49152 gforge01-web   0.0  0.8  11460  4456 ?        S    02:43   0:08 /usr/sbin/apache2 -k start
www-data 30873 49152 gforge01-web   0.0  0.8  11600  4532 ?        S    05:27   0:08 /usr/sbin/apache2 -k start
www-data 30959     0 MAIN           0.0  2.1  42544 11192 ?        S    05:28   0:03 /usr/sbin/apache2 -k start
www-data 30964     0 MAIN           0.0  2.0  43120 10540 ?        S    05:28   0:02 /usr/sbin/apache2 -k start
www-data 32253 49152 gforge01-web   0.0  0.8  11600  4556 ?        S    07:18   0:06 /usr/sbin/apache2 -k start
www-data 32256 49152 gforge01-web   0.0  0.6  10516  3484 ?        S    07:18   0:02 /usr/sbin/apache2 -k start
www-data 32257 49152 gforge01-web   0.0  0.8  11464  4468 ?        S    07:18   0:05 /usr/sbin/apache2 -k start
www-data 32266 49152 gforge01-web   0.0  0.6  10516  3484 ?        S    07:18   0:02 /usr/sbin/apache2 -k start
www-data 32276 49152 gforge01-web   0.0  0.8  11464  4456 ?        S    07:18   0:04 /usr/sbin/apache2 -k start
www-data  7150     0 MAIN           0.0  1.6  42632  8364 ?        S    17:04   0:00 /usr/sbin/apache2 -k start
www-data  7175     0 MAIN           0.0  1.5  41764  8164 ?        S    17:04   0:00 /usr/sbin/apache2 -k start
www-data  7207     0 MAIN           0.0  1.8  42352  9408 ?        S    17:04   0:00 /usr/sbin/apache2 -k start
www-data  7482 49153 gforge01       0.2  2.4  27072 12844 ?        S    17:11   0:45 /usr/sbin/apache2 -k start
mysql     7499 49153 gforge01       0.0  1.4  20836  7436 ?        S    17:12   0:01 postgres: gforge gforge [local] idle
www-data  8064     0 MAIN           0.0  1.4  41836  7608 ?        S    17:54   0:00 /usr/sbin/apache2 -k start
www-data  9227 49153 gforge01       0.1  2.4  26692 12516 ?        S    19:31   0:22 /usr/sbin/apache2 -k start
mysql     9231 49153 gforge01       0.0  1.3  20696  6760 ?        S    19:32   0:00 postgres: gforge gforge [local] idle
www-data  9376     0 MAIN           0.0  1.6  43060  8780 ?        S    19:52   0:00 /usr/sbin/apache2 -k start
www-data  9758 49153 gforge01       0.1  2.3  26640 12368 ?        S    20:32   0:11 /usr/sbin/apache2 -k start
mysql     9765 49153 gforge01       0.0  1.3  20932  6764 ?        S    20:32   0:00 postgres: gforge gforge [local] idle
www-data  9920     0 MAIN           0.0  1.4  41832  7516 ?        S    20:43   0:00 /usr/sbin/apache2 -k start
www-data  9921 49153 gforge01       0.1  2.3  26488 12232 ?        S    20:43   0:13 /usr/sbin/apache2 -k start
www-data  9923     0 MAIN           0.0  1.4  41812  7552 ?        S    20:43   0:00 /usr/sbin/apache2 -k start
www-data  9924 49153 gforge01       0.1  2.3  26252 12004 ?        S    20:43   0:11 /usr/sbin/apache2 -k start
www-data  9928     0 MAIN           0.0  1.7  42220  8912 ?        S    20:43   0:00 /usr/sbin/apache2 -k start
mysql     9935 49153 gforge01       0.0  1.2  20740  6352 ?        S    20:43   0:00 postgres: gforge gforge [local] idle
mysql     9944 49153 gforge01       0.0  1.4  20868  7432 ?        S    20:45   0:00 postgres: gforge gforge [local] idle
www-data 10412 49153 gforge01       0.1  2.4  26748 12468 ?        S    21:33   0:07 /usr/sbin/apache2 -k start
mysql    10420 49153 gforge01       0.0  1.2  20724  6520 ?        S    21:34   0:00 postgres: gforge gforge [local] idle
www-data 10546 49153 gforge01       0.1  2.4  26740 12420 ?        S    21:47   0:05 /usr/sbin/apache2 -k start
mysql    10556 49153 gforge01       0.0  1.2  20724  6576 ?        S    21:48   0:00 postgres: gforge gforge [local] idle
www-data 10619 49153 gforge01       0.1  2.3  26292 11944 ?        S    22:01   0:04 /usr/sbin/apache2 -k start
mysql    10622 49153 gforge01       0.0  1.3  20740  6848 ?        S    22:02   0:00 postgres: gforge gforge [local] idle
root     10999     0 MAIN           0.0  0.4   7704  2304 ?        Ss   22:41   0:00 sshd: daniel [priv]
daniel   11001     0 MAIN           0.0  0.3   7860  1680 ?        S    22:41   0:00 sshd: daniel@pts/0
daniel   11002     0 MAIN           0.0  0.6   5976  3500 pts/0    Ss   22:41   0:00 -bash
root     11046     0 MAIN           0.0  0.2   3712  1088 pts/0    S    22:42   0:00 su
root     11047     0 MAIN           0.0  0.3   3960  1672 pts/0    S    22:42   0:00 bash
www-data 11203 49154 public01       0.0  0.2   3924  1060 ?        S    22:53   0:00 /usr/sbin/lighttpd -f /etc/lighttpd/lighttpd.conf
www-data 11204 49154 public01       0.0  0.9  15040  4672 ?        Ss   22:53   0:00 /usr/bin/php-cgi
www-data 11209 49154 public01       0.1  0.9  15040  4672 ?        Ss   22:53   0:00 /usr/bin/php-cgi
www-data 11210 49154 public01       0.0  0.3  15040  1956 ?        S    22:53   0:00 /usr/bin/php-cgi
www-data 11211 49154 public01       0.0  0.3  15040  1956 ?        S    22:53   0:00 /usr/bin/php-cgi
www-data 11212 49154 public01       0.0  0.3  15040  1956 ?        S    22:53   0:00 /usr/bin/php-cgi
www-data 11213 49154 public01       0.0  0.3  15040  1956 ?        S    22:53   0:00 /usr/bin/php-cgi
www-data 11214 49154 public01       0.0  0.3  15040  1956 ?        S    22:53   0:00 /usr/bin/php-cgi
www-data 11215 49154 public01       0.0  0.3  15040  1956 ?        S    22:53   0:00 /usr/bin/php-cgi
www-data 11216 49154 public01       0.0  0.3  15040  1956 ?        S    22:53   0:00 /usr/bin/php-cgi
www-data 11217 49154 public01       0.0  0.3  15040  1956 ?        S    22:53   0:00 /usr/bin/php-cgi
root     11237     1 ALL_PROC       0.0  0.0    148    48 pts/0    S+   22:54   0:00 vps aux
root     11238     1 ALL_PROC       0.0  0.1   3424  1000 pts/0    R+   22:54   0:00 ps aux


Edit: Added ps output (not that anybody cares :P)
Title: Re: PHP String Replacement Speed Comparison
Post by: Thantos on June 09, 2007, 09:53:42 AM
If anyone else wants to post their test results feel free.  I'll compile them together and post out some analysis of it.
Title: Re: PHP String Replacement Speed Comparison
Post by: winrules on June 09, 2007, 10:34:18 AM
sprintf: 0.886003017426 seconds
preg_replace: 2.66261482239 seconds
strtr: 31.150698185 seconds
str_replace #1: 1.06948304176 seconds
str_replace #2: 1.39181494713 seconds
Title: Re: PHP String Replacement Speed Comparison
Post by: Compuart on June 09, 2007, 04:10:34 PM
Quote from: Thantos on June 03, 2007, 03:00:23 PM
strtr and str_replace both seem to operate the same way.  However, due to strtr's unique properties the results can be very different.
Imho the difference between how the two operate is pretty significant. While strtr will iterate through each character of the search string and attempt to replace anything that it can match at the current offset, str_replace iterates through each search/replacement pair and does the replace operation for the whole subject.

The latter may be faster, but having the replaced subjects being searched and replaced again is often undesirable, especially when dealing with variable searches or replacements (like custom smileys).

Oh and strtr is sooooo much better readable ;)
Title: Re: PHP String Replacement Speed Comparison
Post by: Tristan Perry on June 09, 2007, 05:18:38 PM
Useful test/script :) My results and setup are thus:

Processor: Intel Xeon CPU 5130 @ 2.00GHz (500.026MHz)
RAM: 512 MB
OS: Linux 2.6.9
PHP version: 4.4.6
Load Averages: 0.83, 0.74, 0.54

sprintf: 0.042463 seconds
preg_replace: 0.573575 seconds
strtr: -0.780915 seconds
str_replace #1: 0.206594 seconds
str_replace #2: 0.520598 seconds

- not sure why I got a negative time ??? I guess this means that strtr() is SO powerful and quick, that it'll actually sort out your scripts before they need to be run! Awesome! Psychic PHP functions are always fun :P See, strtr is the best function (plus it's really readable, as Compuart said ;))
Title: Re: PHP String Replacement Speed Comparison
Post by: Thantos on June 09, 2007, 09:21:00 PM
Quote from: Compuart on June 09, 2007, 04:10:34 PM
Quote from: Thantos on June 03, 2007, 03:00:23 PM
strtr and str_replace both seem to operate the same way.  However, due to strtr's unique properties the results can be very different.
Imho the difference between how the two operate is pretty significant. While strtr will iterate through each character of the search string and attempt to replace anything that it can match at the current offset, str_replace iterates through each search/replacement pair and does the replace operation for the whole subject.

The latter may be faster, but having the replaced subjects being searched and replaced again is often undesirable, especially when dealing with variable searches or replacements (like custom smileys).

Oh and strtr is sooooo much better readable ;)
Thats why you use strtr when you need to.  I'm not advocating not using strtr when you need its properties but to use strtr when you want str_replace behavior is bad.  But if you don't need that functionality then why use a slower option?
As for readability it really is minor as you can still define the replacement array the same way and then use array_key() to seperate the from and to.  As show by str_replace #2 it is still faster then strtr.
Title: Re: PHP String Replacement Speed Comparison
Post by: Daniel15 on June 09, 2007, 09:32:27 PM
Quote- not sure why I got a negative time
Sounds like you're using PHP 4 rather than PHP 5. PHP 5 changed the behaviour of microtime(). Basically, if you pass it "true" as a parameter, it returns the value as a float (PHP 4 returned two values seperated by a space, as does PHP 5 without any parameters).

To make it work properly on PHP 4, add this to the start of the file (below the <?php):

function microtime_float()
{
    list($usec, $sec) = explode(" ", microtime());
    return ((float)$usec + (float)$sec);
}


Then, in the script, replace all instances of

microtime(true)

with

microtime_float()
Title: Re: PHP String Replacement Speed Comparison
Post by: KGIII on June 09, 2007, 10:20:04 PM
Would you like tests from multiple servers perhaps or just one result per person will be enough for an informal test such as this?
Title: Re: PHP String Replacement Speed Comparison
Post by: ディン1031 on June 10, 2007, 09:52:30 AM
On my small Private Windows Test Server
Processor: Intel Core2Duo 6600 @ 2.40GHz
RAM: 2048 MB
Operating System:     Microsoft Windows XP [Version 5.1.2600]
Current processes:    47 (47 running, 0 zombie)
PHP version: 5.1.4
Server version: Apache/2.2.2 (Win32) DAV/2 mod_ssl/2.2.2 OpenSSL/0.9.8b mod_autoindex_color PHP/5.1.4

sprintf: 0.73141002655 seconds
preg_replace: 1.26732420921 seconds
strtr: 23.7995750904 seconds
str_replace #1: 0.864935159683 seconds
str_replace #2: 1.10788106918 seconds


(Or should i test it on my other server with linux on it :x).

Bye
DIN1031


Title: Re: PHP String Replacement Speed Comparison
Post by: Saleh on June 11, 2007, 07:57:38 AM
OS: Windows XP Media Center SP2
CPU: Intel CentrinoDuo T7200 @ 2.00GHz
RAM: 1 GB @ 2.00 GHz
Server: Apache 1.3.34 w/ PHP5 mod
PHP: 5.2.2

Results:
sprintf: 0.80260682106018 seconds
preg_replace: 2.3465528488159 seconds
strtr: 26.90654706955 seconds
str_replace #1: 0.83384084701538 seconds
str_replace #2: 1.1157829761505 seconds

although running this test on windows is kinda useless but meh
anyhow, PHP uses only 1 processor and leaves the other so I was running 50% CPU all the time.


Results from my webhosting account:

Operating system: FreeBSD
Kernel version: 6.1-RELEASE-p4
Machine Type: amd64
Apache version: 1.3.37 (Unix)
PHP version 4.4.2  (outdated!?)

RUN 1:
Server Load: 1.03 (2 cpus) 
Memory Used: 67.77 %
sprintf: 1.22852993011 seconds
preg_replace: 2.19928884506 seconds
strtr: 41.4552869797 seconds
str_replace #1: 1.34867596626 seconds
str_replace #2: 1.66192102432 seconds


RUN 2:
Server Load 0.88 (2 cpus) 
Memory Used 62.88 %
sprintf: 1.16300082207 seconds
preg_replace: 1.57117605209 seconds
strtr: 34.872027874 seconds
str_replace #1: 1.37249684334 seconds
str_replace #2: 1.51887798309 seconds

RUN 3:
Server Load 1.50 (2 cpus) 
Memory Used 65.80 %
sprintf: 1.24492406845 seconds
preg_replace: 1.72587108612 seconds
strtr: 36.0469529629 seconds
str_replace #1: 1.16329097748 seconds
str_replace #2: 1.65367412567 seconds

Note all those server status were taken the moment the benchmark started
Title: Re: PHP String Replacement Speed Comparison
Post by: SleePy on June 11, 2007, 06:48:25 PM
Quotesprintf: 1.5811309814453 seconds
preg_replace: 2.1888408660889 seconds
strtr: 45.443498849869 seconds
str_replace #1: 2.333279132843 seconds
str_replace #2: 2.0846509933472 seconds
Kinda high because I was running a php script already before that that does take up some processes.

For anyone with max_execution_time error add this to the top of the file just after the <?php
set_time_limit(120);
Title: Re: PHP String Replacement Speed Comparison
Post by: Daniel15 on June 12, 2007, 02:04:13 AM
And here's mine from my web hosting server:
Quotedaniel15@blue [~/tmp]# ./benchmark.php
sprintf: 0.950059890747 seconds
preg_replace: 1.63948893547 seconds
strtr: 38.4129178524 seconds
str_replace #1: 0.748620033264 seconds
str_replace #2: 0.989835977554 seconds

System information:
Quote

daniel15@blue [~/tmp]# uname -a
Linux blue.inviohosting.com 2.6.9-55.EL #1 Wed May 2 13:52:16 EDT 2007 i686 athlon i386 GNU/Linux

daniel15@blue [~/tmp]# php -v
PHP 5.2.2 with Suhosin-Patch 0.9.6.2 (cli) (built: May 11 2007 23:54:15)
Copyright (c) 1997-2007 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies
    with XCache v1.2.0, Copyright (c) 2005-2006, by mOo

daniel15@blue [~/tmp]# uptime
01:02:57 up 24 days, 15:04,  1 user,  load average: 0.04, 0.10, 0.15

daniel15@blue [~/tmp]# cat /proc/cpuinfo
processor       : 0
vendor_id       : AuthenticAMD
cpu family      : 15
model           : 47
model name      : AMD Athlon(tm) 64 Processor 3800+
stepping        : 2
cpu MHz         : 2389.466
cache size      : 512 KB
fdiv_bug        : no
hlt_bug         : no
f00f_bug        : no
coma_bug        : no
fpu             : yes
fpu_exception   : yes
cpuid level     : 1
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 pni syscall nx mmxext fxsr_opt lm 3dnowext 3dnow pni
bogomips        : 4780.45



daniel15@blue [~/tmp]# ps aux
USER       PID %CPU %MEM   VSZ  RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0  2460  452 ?        S    May18   0:01 init [3]         
root         2  0.0  0.0     0    0 ?        SN   May18   0:00 [ksoftirqd/0]
root         3  0.0  0.0     0    0 ?        S<   May18   0:00 [events/0]
root         4  0.0  0.0     0    0 ?        S<   May18   0:00 [khelper]
root         5  0.0  0.0     0    0 ?        S<   May18   0:00 [kacpid]
root        29  0.0  0.0     0    0 ?        S<   May18   0:00 [kblockd/0]
root        30  0.0  0.0     0    0 ?        S    May18   0:00 [khubd]
root        49  0.0  0.0     0    0 ?        S    May18   0:31 [kswapd0]
root        50  0.0  0.0     0    0 ?        S<   May18   0:00 [aio/0]
root       194  0.0  0.0     0    0 ?        S    May18   0:00 [kseriod]
root       418  0.0  0.0     0    0 ?        S<   May18   0:00 [ata/0]
root       419  0.0  0.0     0    0 ?        S<   May18   0:00 [ata_aux]
root       421  0.0  0.0     0    0 ?        S    May18   0:00 [scsi_eh_0]
root       422  0.0  0.0     0    0 ?        S    May18   0:00 [scsi_eh_1]
root       434  0.0  0.0     0    0 ?        S    May18   5:27 [kjournald]
root      1578  0.0  0.3 10376 3488 ?        S    May18   1:29 lfd - sleeping
root      1698  0.0  0.0  3176  356 ?        S<s  May18   0:00 udevd
root      1881  0.0  0.0     0    0 ?        S<   May18   0:00 [kedac]
root      2025  0.0  0.0     0    0 ?        S<   May18   0:00 [kauditd]
root      2088  0.0  0.0     0    0 ?        S    May18   0:00 [kjournald]
root      2734  0.0  0.0  2556  516 ?        Ss   May18   1:24 syslogd -m 0
root      2738  0.0  0.0  2260  376 ?        Ss   May18   0:01 klogd -x
named     2760  0.0  0.2 39232 2692 ?        Ssl  May18   1:35 /usr/sbin/named -u named
root      2834  0.0  0.0  4232  200 ?        Ss   May18   0:00 rpc.idmapd
root      2995  0.0  0.0  4256  164 ?        Ss   May18   0:00 /var/dcc/libexec/dccifd -tCMN,5, -llog -wwhiteclnt -Uuserdirs -SHELO -Smail_host -SSender -SLi
root      2996  0.0  0.1 47112 1500 ?        Sl   May18   0:03 /var/dcc/libexec/dccifd -tCMN,5, -llog -wwhiteclnt -Uuserdirs -SHELO -Smail_host -SSender -SLi
root      3007  0.0  0.0  3152  436 ?        S    May18   0:00 /usr/sbin/smartd
root      3016  0.0  0.0  2620  360 ?        Ss   May18   0:00 /usr/sbin/acpid
root      3039  0.0  0.0  2320  516 ?        Ss   May18   0:00 xinetd -stayalive -pidfile /var/run/xinetd.pid
root      4144  0.0  0.0  7316  696 ?        Ss   May18   0:00 pure-ftpd (SERVER)                                                                           
root      4148  0.0  0.0  6916  592 ?        S    May18   0:00 /usr/sbin/pure-authd -s /var/run/ftpd.sock -r /usr/sbin/pureauth
root      4289  0.0  0.1  5168 1064 ?        S    May18   0:00 /bin/sh /usr/bin/mysqld_safe --datadir=/var/lib/mysql --pid-file=/var/lib/mysql/blue.inviohost
mysql     4318  0.1  6.0 208000 58800 ?      Sl   May18  70:01 /usr/sbin/mysqld --basedir=/ --datadir=/var/lib/mysql --user=mysql --pid-file=/var/lib/mysql/b
root      4350  0.0  0.2  9792 2396 ?        Ss   May18   0:04 /usr/sbin/munin-node
xfs       4470  0.0  0.0  3700  616 ?        Ss   May18   0:00 xfs -droppriv -daemon
dbus      4727  0.0  0.0  2524  300 ?        Ss   May18   0:00 dbus-daemon-1 --system
root      4737  0.0  0.1  7012 1412 ?        Ss   May18   0:01 hald
root      4759  0.0  0.0  1488  336 ?        Ss   May18   0:00 /usr/sbin/portsentry -tcp
root      4939  0.0  0.0     0    0 ?        S<   May18   0:21 [loop0]
root      4940  0.0  0.0     0    0 ?        S    May18   0:01 [kjournald]
root      4947  0.0  0.0  2052  328 tty1     Ss+  May18   0:00 /sbin/mingetty tty1
root      4948  0.0  0.0  1564  328 tty2     Ss+  May18   0:00 /sbin/mingetty tty2
root      4949  0.0  0.0  2776  328 tty3     Ss+  May18   0:00 /sbin/mingetty tty3
root      4950  0.0  0.0  2392  328 tty4     Ss+  May18   0:00 /sbin/mingetty tty4
root      4951  0.0  0.0  2700  328 tty5     Ss+  May18   0:00 /sbin/mingetty tty5
root      4952  0.0  0.0  2988  328 tty6     Ss+  May18   0:00 /sbin/mingetty tty6
root      5394  0.0  0.0  1524  384 ?        S    Jun10   0:00 /usr/sbin/courierlogger -pid=/var/run/imapd.pid -start -name=imapd /usr/lib/courier-imap/libex
root      5395  0.0  0.0  2108  472 ?        S    Jun10   0:00 /usr/lib/courier-imap/libexec/couriertcpd -address=0 -maxprocs=40 -maxperip=30 -nodnslookup -n
root      5401  0.0  0.0  2252  236 ?        S    Jun10   0:00 /usr/sbin/courierlogger -pid=/var/run/imapd-ssl.pid -start -name=imapd-ssl /usr/lib/courier-im
root      5402  0.0  0.0  1704  400 ?        S    Jun10   0:00 /usr/lib/courier-imap/libexec/couriertcpd -address=0 -maxprocs=40 -maxperip=30 -nodnslookup -n
root      5407  0.0  0.0  2500  384 ?        S    Jun10   0:00 /usr/sbin/courierlogger -pid=/var/run/pop3d.pid -start -name=pop3d /usr/lib/courier-imap/libex
root      5408  0.0  0.0  3088  472 ?        S    Jun10   0:00 /usr/lib/courier-imap/libexec/couriertcpd -address=0 -maxprocs=40 -maxperip=30 -nodnslookup -n
root      5413  0.0  0.0  3340  236 ?        S    Jun10   0:00 /usr/sbin/courierlogger -pid=/var/run/pop3d-ssl.pid -start -name=pop3d-ssl /usr/lib/courier-im
root      5414  0.0  0.0  2504  400 ?        S    Jun10   0:00 /usr/lib/courier-imap/libexec/couriertcpd -address=0 -maxprocs=40 -maxperip=30 -nodnslookup -n
root      5419  0.0  0.0  2956  320 ?        S    Jun10   0:00 /usr/sbin/courierlogger -pid=/var/spool/authdaemon/pid -facility=mail -start /usr/libexec/cour
root      5420  0.0  0.0  3136  488 ?        S    Jun10   0:00 /usr/libexec/courier-authlib/authdaemond
root      5424  0.0  0.0  3136  308 ?        S    Jun10   0:00 /usr/libexec/courier-authlib/authdaemond
root      5425  0.0  0.0  3136  308 ?        S    Jun10   0:00 /usr/libexec/courier-authlib/authdaemond
root      5426  0.0  0.0  3136  312 ?        S    Jun10   0:00 /usr/libexec/courier-authlib/authdaemond
root      5427  0.0  0.0  3136  308 ?        S    Jun10   0:00 /usr/libexec/courier-authlib/authdaemond
root      5428  0.0  0.0  3136  264 ?        S    Jun10   0:00 /usr/libexec/courier-authlib/authdaemond
root      6517  0.0  0.0  4760  908 ?        Ss   May19   0:00 crond
root      7475  0.0  0.2  6444 2032 ?        S    Jun10   0:00 cpbandwd
root     10276  0.0  0.1  8668 1712 ?        S    Jun10   0:00 /usr/bin/perl /usr/local/cpanel/bin/leechprotect
nobody   10277  0.1  1.6 41608 16264 ?       S    Jun10   2:06 /usr/local/apache/bin/httpd
nobody   10278  0.1  2.0 51820 19976 ?       S    Jun10   2:03 /usr/local/apache/bin/httpd
nobody   10279  0.1  1.7 63640 16816 ?       S    Jun10   2:01 /usr/local/apache/bin/httpd
nobody   10280  0.1  2.5 52272 25040 ?       S    Jun10   2:07 /usr/local/apache/bin/httpd
nobody   10281  0.1  1.7 54600 16736 ?       S    Jun10   2:00 /usr/local/apache/bin/httpd
nobody   10285  0.1  1.7 58620 17072 ?       S    Jun10   2:11 /usr/local/apache/bin/httpd
nobody   10300  0.1  1.6 53608 16060 ?       S    Jun10   1:53 /usr/local/apache/bin/httpd
nobody   10303  0.1  1.7 39252 16800 ?       S    Jun10   2:01 /usr/local/apache/bin/httpd
nobody   10304  0.1  1.7 42124 16616 ?       S    Jun10   2:12 /usr/local/apache/bin/httpd
nobody   10306  0.1  1.9 50428 18424 ?       S    Jun10   2:15 /usr/local/apache/bin/httpd
root     10576  0.0  0.6 12748 6352 ?        SN   Jun10   0:30 cpanellogd - sleeping for logs
mailnull 10589  0.0  0.2  7264 2096 ?        S    Jun10   0:00 eximstats
mailman  10597  0.0  0.0 11984  948 ?        Ss   Jun10   0:00 /usr/local/bin/python2.4 /usr/local/cpanel/3rdparty/mailman/bin/mailmanctl -s start
mailman  10608  0.0  0.3 12120 2936 ?        S    Jun10   0:00 /usr/local/bin/python2.4 /usr/local/cpanel/3rdparty/mailman/bin/qrunner --runner=ArchRunner:0:
mailman  10609  0.0  0.3 10564 2968 ?        S    Jun10   0:00 /usr/local/bin/python2.4 /usr/local/cpanel/3rdparty/mailman/bin/qrunner --runner=BounceRunner:
mailman  10610  0.0  0.3 10660 2940 ?        S    Jun10   0:00 /usr/local/bin/python2.4 /usr/local/cpanel/3rdparty/mailman/bin/qrunner --runner=CommandRunner
mailman  10611  0.0  0.3 10740 2984 ?        S    Jun10   0:00 /usr/local/bin/python2.4 /usr/local/cpanel/3rdparty/mailman/bin/qrunner --runner=IncomingRunne
mailman  10612  0.0  0.3 10192 2948 ?        S    Jun10   0:00 /usr/local/bin/python2.4 /usr/local/cpanel/3rdparty/mailman/bin/qrunner --runner=NewsRunner:0:
mailman  10613  0.0  0.3 10768 3116 ?        S    Jun10   0:00 /usr/local/bin/python2.4 /usr/local/cpanel/3rdparty/mailman/bin/qrunner --runner=OutgoingRunne
mailman  10614  0.0  0.3 11460 3012 ?        S    Jun10   0:00 /usr/local/bin/python2.4 /usr/local/cpanel/3rdparty/mailman/bin/qrunner --runner=VirginRunner:
mailman  10615  0.0  0.3 10272 2956 ?        S    Jun10   0:00 /usr/local/bin/python2.4 /usr/local/cpanel/3rdparty/mailman/bin/qrunner --runner=RetryRunner:0
nobody   10640  0.0  0.0  5716  584 ?        S    Jun10   0:00 entropychat
root     10645  0.0  0.0 14556  268 ?        S    Jun10   0:00 cpdavd - accepting connections on 2077 and 2078
root     12454  0.0  0.1  5296 1860 ?        S    Jun10   0:01 /etc/authlib/authProg
root     12469  0.0  0.1  5296 1900 ?        S    Jun10   0:00 /etc/authlib/authProg
root     13154  0.0  0.1  5296 1888 ?        S    Jun10   0:00 /etc/authlib/authProg
root     15969  0.0  0.0     0    0 ?        S    Jun11   0:00 [pdflush]
root     21223  0.0  0.1  5296 1924 ?        S    Jun10   0:01 /etc/authlib/authProg
root     21955  0.0  1.0 23904 10080 ?       Ss   Jun10   0:01 /usr/local/apache/bin/httpd
root     23158  0.0  0.0     0    0 ?        S    May26   0:07 [pdflush]
root     24093  0.0  0.5  9088 4956 ?        S    Jun11   0:00 chkservd
root     26135  0.8  2.7 31232 26300 ?       Ss   00:33   0:16 /usr/sbin/clamd
mailnull 26141  0.0  0.0  9200  908 ?        Ss   00:33   0:00 /usr/sbin/exim -bd -q60m
mailnull 26146  0.0  0.0  8768  852 ?        Ss   00:33   0:00 /usr/sbin/exim -tls-on-connect -bd -oX 465
root     26152  0.0  0.1  4120 1140 ?        S    00:33   0:00 antirelayd
root     26168  0.0  4.1 43404 39948 ?       Ss   00:33   0:01 /usr/bin/spamd -d --allowed-ips=127.0.0.1 --pidfile=/var/run/spamd.pid --max-children=5
root     26172  0.0  4.1 43812 40084 ?       S    00:33   0:00 spamd child
root     26173  0.0  3.9 43404 38324 ?       S    00:33   0:00 spamd child
32029    26827  0.0  0.1  4048 1432 ?        S    00:41   0:00 /usr/lib/courier-imap/bin/imapd /home/dansoft/mail
daniel15 26828  0.0  0.1  4776 1052 ?        S    00:41   0:00 /usr/lib/courier-imap/bin/imapd /home/daniel15/mail
32004    26829  0.0  0.0  3708  764 ?        S    00:41   0:00 /usr/lib/courier-imap/bin/imapd /home/invio/mail/inviohosting.com/daniel
root     26993  0.0  1.0 20320 9932 ?        S    Jun11   0:00 cpsrvd - waiting for connections
root     27871  0.0  0.2  7964 2244 ?        Ss   00:56   0:00 sshd: daniel15 [priv]
daniel15 27873  0.0  0.1  8108 1720 ?        S    00:56   0:00 sshd: daniel15@pts/1
root     27874  0.0  0.0  1520  552 ?        Ss   00:56   0:00 -jailshell
daniel15 27885  0.0  0.1  2968 1312 ?        S    00:56   0:00 -jailshell
nobody   28358  0.0  0.9 24036 9468 ?        S    01:04   0:00 /usr/local/apache/bin/httpd
daniel15 28683  0.0  0.0  2960  788 ?        R+   01:05   0:00 ps aux
root     31622  0.0  0.2  5296 2008 ?        S    Jun11   0:00 /etc/authlib/authProg
root     32657  0.0  0.0  5736  772 ?        Ss   May26   0:00 /usr/sbin/sshd

("ps" output in code box because it's long :P)

I love using a relatively small web host - The load average is awesome. I actually do maintenance work for the host (InVio Hosting) :D
Title: Re: PHP String Replacement Speed Comparison
Post by: Joshua Dickerson on June 12, 2007, 09:24:36 AM
sprintf() isn't really in the same boat as the other string replacement functions IMO. It is more of a fancy concatenation and in that boat, it isn't so fast. If you have a string that looks like your sprintf() string and you want to return or output it, use a language construct (double quotes, dots, commas, etc) instead.
Title: Re: PHP String Replacement Speed Comparison
Post by: Thantos on June 12, 2007, 10:39:42 AM
There is of course one major problem with doing that:  It requires you to determine the language grammer in the source and not in the language strings.

Lets take the following statement:
My name is {NAME} and I am a {JOB} here at {COMPANY} where I work for {BOSSTITLE} {BOSS}
example:  My name is Thantos and I am a developer here at Simple Machines where I work for Lead Developer Compuart

Now if I wanted to that with concatation (of any sort) it would be something like: ($t is an array of language strings)
$t[1] . $name . $t[2] . $job . $t[3] . $company . $t[4] . $bosstitle . ' ' . $boss
So if I wanted to that sentence I'd need to use four text strings.  But now lets say for my particular setting "Lead Developer Compuart" isn't proper, I need "Compuart the Lead Developer".  Not only have I inserted another text string ("the") but I have rearranged the order in which the data appears.  No amount of changing of (just text strings) $t[1] . $name . $t[2] . $job . $t[3] . $company . $t[4] . $bosstitle . ' ' . $boss
is going to get me My name is Thantos and I am a developer here at Simple Machines where I work for Compuart the Lead Developer

Now if I put it all into one text string and use some some sequence identifiers I can do this:
My name is %1$s and I am a %2$s here at %3$s where I work for %4$s %5$s
and call it like: $str = sprintf($text, $name, $job, $company, $bosstitle, $boss);
Now if they want to make the change I did then it is a simple edit job to the language string
My name is %1$s and I am a %2$s here at %3$s where I work for %5$s the %4$s

Heck you could even leave the boss title out and have
My name is %1$s and I am a %2$s here at %3$s where I work for %5$s

One thing to consider is if you want to use
My name is %1$s and I am a %2$s here at %3$s where I work for %4$s %5$s
and gain the speed or use
My name is {NAME} and I am a {JOB} here at {COMPANY} where I work for {BOSSTITLE} {BOSS}
and gain the readability.

That choice depends mostly on how the string is being used.
Title: Re: PHP String Replacement Speed Comparison
Post by: Joshua Dickerson on June 12, 2007, 04:15:16 PM
What's wrong with the following:
$str  = "My name is $NAME and I am a $JOB here at $COMPANY where I work for $BOSSTITLE $BOSS";
Title: Re: PHP String Replacement Speed Comparison
Post by: Thantos on June 12, 2007, 04:28:24 PM
Can you export that into a language file so it can be translated into other languages?

What happens if you load the file that contains the string and those variables aren't defined yet?
Title: Re: PHP String Replacement Speed Comparison
Post by: Joshua Dickerson on June 12, 2007, 04:35:57 PM
Quote from: groundup on June 12, 2007, 04:15:16 PM
$txt['no_sprintf']  = "My name is $GLOBALS[NAME] and I am a $GLOBALS[JOB] here at $GLOBALS[COMPANY] where I work for $GLOBALS[BOSSTITLE] $GLOBALS[BOSS]";
or something similar to that. As for not being defined, okay, I guess there is where you have the difference. Although, %1$s can hardly be considered readable.
Title: Re: PHP String Replacement Speed Comparison
Post by: SleePy on June 12, 2007, 04:49:47 PM
Quote from: groundup on June 12, 2007, 04:35:57 PM
Quote from: groundup on June 12, 2007, 04:15:16 PM
$txt['no_sprintf']  = "My name is $GLOBALS[NAME] and I am a $GLOBALS[JOB] here at $GLOBALS[COMPANY] where I work for $GLOBALS[BOSSTITLE] $GLOBALS[BOSS]";
or something similar to that. As for not being defined, okay, I guess there is where you have the difference. Although, %1$s can hardly be considered readable.

Still isn't very readable. But I choose speed over readability of the language strings myself ;) I don't care if I can't read them if it makes my forum twice as fast to use it another way I will.
Title: Re: PHP String Replacement Speed Comparison
Post by: Joshua Dickerson on June 12, 2007, 05:33:36 PM
If you want speed, language constructs work better. Although, the speed difference between all of these is very little.
Title: Re: PHP String Replacement Speed Comparison
Post by: Daniel15 on June 13, 2007, 01:07:06 AM
Quotesprintf() isn't really in the same boat as the other string replacement functions IMO. It is more of a fancy concatenation and in that boat, it isn't so fast.
It's not classified as "fancy concatenation"; it's classified as string formatting ;). Still, I agree in a sense - It is a formatting function, not a replacement function :)
And I agree with Thantos' large post above :)