Re: [PHP] Pointers For Newbies, Reminders For Oldies
On Sat, 2010-01-30 at 13:02 +1100, clanc...@cybec.com.au wrote: > On Thu, 28 Jan 2010 10:02:56 -0500, rob...@interjinn.com (Robert Cummings) > wrote: > > > >I don't know what you guys are doing wrong but the following should be > >the correct behaviour: > > > > > > >function get_memory( $init=false ) > >{ > > static $base = null; > > if( $base === null || $init ) > > { > > $base = memory_get_usage(); > > } > > > > return memory_get_usage() - $base; > >} > > > >function simple_access( $data ) > >{ > > $foo = $data[100]; > > echo 'Memory: '.get_memory().' (simple access)'."\n"; > >} > > > >function foreach_value_access( $data ) > >{ > > foreach( $data as $value ) > > { > > $foo = $value; > > break; > > } > > echo 'Memory: '.get_memory().' (foreach value access)'."\n"; > >} > > > >function foreach_key_access( $data ) > >{ > > foreach( $data as $key => $value ) > > { > > $foo = $key; > > $foo = $value; > > break; > > } > > echo 'Memory: '.get_memory().' (foreach key/value access)'."\n"; > >} > > > >function modify_single_access( $data ) > >{ > > $data[100] = str_repeat( '@', 1 ); > > echo 'Memory: '.get_memory().' (modify single access)'."\n"; > >} > > > >function modify_all_access( $data ) > >{ > > for( $i = 0; $i < 1000; $i++ ) > > { > > $data[$i] = str_repeat( '@', 1 ); > > } > > > > echo 'Memory: '.get_memory().' (modify all access)'."\n"; > >} > > > > > >get_memory( true ); > > > >$data = array(); > >for( $i = 0; $i < 1000; $i++ ) > >{ > > $data[$i] = str_repeat( '#', 1 ); > >} > > > >echo 'Memory: '.get_memory().' (data initialized)'."\n"; > > > >simple_access( $data ); > >foreach_value_access( $data ); > >foreach_key_access( $data ); > >modify_single_access( $data ); > >modify_all_access( $data ); > > > >?> > > > >I get the following output (PHP 5.2.11 from command-line): > > > > Memory: 10160768 (data initialized) > > Memory: 10161008 (simple access) > > Memory: 10161104 (foreach value access) > > Memory: 10161240 (foreach key/value access) > > Memory: 10267312 (modify single access) > > Memory: 20321576 (modify all access) > > > >I don't double up on memory consumption until I force the write onto > >every element... this is expected because internally every array element > >is individually subject to the Copy-On-Write (COW) principle since each > >element is internally stored as a zval just like the array itself. > > Thanks for this. I was just revising a bit of code to insert some extra > entries into an > array. Previously I had opened a new array, copied the data up to the > insertion point into > it, put in the new entry, then copied the tail, then renamed the new array. > After reading > this, I realise the correct procedure was to copy the existing data into a > temporary > array, insert the new entry in the existing array, and then copy the tail > from the copy > back into the working data. > > This way only the data in the tail actually has to be copied, rather than the > whole array. > Erm, what about array_splice()? You can use that to insert items into an array at any point you want. Thanks, Ash http://www.ashleysheridan.co.uk
Re: [PHP] Pointers For Newbies, Reminders For Oldies
On Thu, 28 Jan 2010 10:02:56 -0500, rob...@interjinn.com (Robert Cummings) wrote: >I don't know what you guys are doing wrong but the following should be >the correct behaviour: > > >function get_memory( $init=false ) >{ > static $base = null; > if( $base === null || $init ) > { > $base = memory_get_usage(); > } > > return memory_get_usage() - $base; >} > >function simple_access( $data ) >{ > $foo = $data[100]; > echo 'Memory: '.get_memory().' (simple access)'."\n"; >} > >function foreach_value_access( $data ) >{ > foreach( $data as $value ) > { > $foo = $value; > break; > } > echo 'Memory: '.get_memory().' (foreach value access)'."\n"; >} > >function foreach_key_access( $data ) >{ > foreach( $data as $key => $value ) > { > $foo = $key; > $foo = $value; > break; > } > echo 'Memory: '.get_memory().' (foreach key/value access)'."\n"; >} > >function modify_single_access( $data ) >{ > $data[100] = str_repeat( '@', 1 ); > echo 'Memory: '.get_memory().' (modify single access)'."\n"; >} > >function modify_all_access( $data ) >{ > for( $i = 0; $i < 1000; $i++ ) > { > $data[$i] = str_repeat( '@', 1 ); > } > > echo 'Memory: '.get_memory().' (modify all access)'."\n"; >} > > >get_memory( true ); > >$data = array(); >for( $i = 0; $i < 1000; $i++ ) >{ > $data[$i] = str_repeat( '#', 1 ); >} > >echo 'Memory: '.get_memory().' (data initialized)'."\n"; > >simple_access( $data ); >foreach_value_access( $data ); >foreach_key_access( $data ); >modify_single_access( $data ); >modify_all_access( $data ); > >?> > >I get the following output (PHP 5.2.11 from command-line): > > Memory: 10160768 (data initialized) > Memory: 10161008 (simple access) > Memory: 10161104 (foreach value access) > Memory: 10161240 (foreach key/value access) > Memory: 10267312 (modify single access) > Memory: 20321576 (modify all access) > >I don't double up on memory consumption until I force the write onto >every element... this is expected because internally every array element >is individually subject to the Copy-On-Write (COW) principle since each >element is internally stored as a zval just like the array itself. Thanks for this. I was just revising a bit of code to insert some extra entries into an array. Previously I had opened a new array, copied the data up to the insertion point into it, put in the new entry, then copied the tail, then renamed the new array. After reading this, I realise the correct procedure was to copy the existing data into a temporary array, insert the new entry in the existing array, and then copy the tail from the copy back into the working data. This way only the data in the tail actually has to be copied, rather than the whole array. -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Pointers For Newbies, Reminders For Oldies
Paul M Foster wrote: On Thu, Jan 28, 2010 at 11:41:43AM -, Ford, Mike wrote: -Original Message- From: Rene Veerman [mailto:rene7...@gmail.com] Sent: 27 January 2010 22:46 And if your script needs to pass large (> 5Mb) arrays around to functions, be sure to use passing-by-reference; failing to do so can double your memory requirements, possibly hitting the ini_set('memory_lmit', ??) Have you benchmarked this? PHP's copy-on-change philosophy means there shouldn't be much difference in memory terms -- so unless you actually expect to change the array's contents, you should pass by value. As proof, I constructed this little test: All in all, there is no evidence that passing arrays to functions by value is inherently more expensive than by reference, and in fact in some cases it can be significantly cheaper. Which in turn says that you should only pass arguments by reference when you actually expect to change them, which is after all what the by-reference operator is there for in the first place! QED. Counter-intuitive benchmarks. Can we not? Benchmarking something on a given version of PHP is nice, but changes to the PHP engine occur on a relatively routine basis. Shall we benchmark each "tip" each time we change PHP versions, and then rework all our code to conform to the latest benchmark, depending on the version of PHP our code is running under? I've been working with PHP for about 9 years now... I believe Copy-On-Write was implemented at the outset of PHP 4. This isn't a feature that tends to change from one version to the next. This feature has a very very specific purpose and it's a purpose that won't be discarded anytime soon... if ever. A better example might be the use of single, versus double quotes. Regardless of benchmarks, it's logically obvious that if the PHP engine doesn't have to evaluate the contents inside single quotes, an expression's evaluation should take less time and use fewer system resources. Naturally, the PHP engine could be tweaked to equalize evaluation between single- and double-quote expressions. But this could also change as the PHP engine is changed. Single versus double isn't much of an argument... inefficient opcode generation in the past made one more lucrative than the other, but this has been pretty much eliminated in the 5 series. As a result of better opcode generation, the hit to parsing double versus single quotes should only be happening at the parse stage, not at the run stage. To put it more simply, we can say that, depending on the version of PHP, single-quoted versus double-quoted expressions will be evaluated in equal amounts of time and using equivalent system resources. And if you prefer to double-quote everything, by all means do so. But the fact remains that the documentation for PHP says that the contents of a string delimited by single quotes will not be evaluated, whereas those within double quotes will be. This is true to a point... but if we have the following: echo "blah $foo bleh"; And this produces opcodes: SET tvar "blah " CAT tvar $foo CAT tvar " bleh" ECHO tvar And then we have: echo 'blah'.$foo.' bleh'; And this produces opcodes: SET tvar "blah " CAT tvar $foo CAT tvar " bleh" ECHO tvar Then beyond the parse stage these are obviously identical. Thus, in my own code these days, I use whichever one makes the content easier to read. For embedding vars into regular content I use double quotes, for outputing HTML I tend to use single quotes so that I don' t need to escape the double quotes for the tag attributes. What these tips are about is coding things using best practices, derived from logical examination of the way PHP is advertised to function, not transitory benchmarks. It helps to have a keen insight into not just how to use PHP, but how PHP itself works. This is where studying history, the PHP code itself, parsers, compilers, optimizers, virtual engines, etc will aid in your understanding of the underlying architecture. Of course, many of these pursuits lie more in the field of Computer Science than in the realm code monkeying :) Cheers, Rob. -- http://www.interjinn.com Application and Templating Framework for PHP -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Pointers For Newbies, Reminders For Oldies
On Thu, Jan 28, 2010 at 11:41:43AM -, Ford, Mike wrote: > > -Original Message- > > From: Rene Veerman [mailto:rene7...@gmail.com] > > Sent: 27 January 2010 22:46 > > > > And if your script needs to pass large (> 5Mb) arrays around to > > functions, be sure to use passing-by-reference; failing to do so can > > double your memory requirements, > > possibly hitting the ini_set('memory_lmit', ??) > > Have you benchmarked this? PHP's copy-on-change philosophy means there > shouldn't be much difference in memory terms -- so unless you actually expect > to change the array's contents, you should pass by value. > > As proof, I constructed this little test: > All in all, there is no evidence that passing arrays to functions by value is > inherently more expensive than by reference, and in fact in some cases it can > be significantly cheaper. Which in turn says that you should only pass > arguments by reference when you actually expect to change them, which is > after all what the by-reference operator is there for in the first place! QED. > Counter-intuitive benchmarks. Can we not? Benchmarking something on a given version of PHP is nice, but changes to the PHP engine occur on a relatively routine basis. Shall we benchmark each "tip" each time we change PHP versions, and then rework all our code to conform to the latest benchmark, depending on the version of PHP our code is running under? A better example might be the use of single, versus double quotes. Regardless of benchmarks, it's logically obvious that if the PHP engine doesn't have to evaluate the contents inside single quotes, an expression's evaluation should take less time and use fewer system resources. Naturally, the PHP engine could be tweaked to equalize evaluation between single- and double-quote expressions. But this could also change as the PHP engine is changed. To put it more simply, we can say that, depending on the version of PHP, single-quoted versus double-quoted expressions will be evaluated in equal amounts of time and using equivalent system resources. And if you prefer to double-quote everything, by all means do so. But the fact remains that the documentation for PHP says that the contents of a string delimited by single quotes will not be evaluated, whereas those within double quotes will be. What these tips are about is coding things using best practices, derived from logical examination of the way PHP is advertised to function, not transitory benchmarks. Paul -- Paul M. Foster -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Pointers For Newbies, Reminders For Oldies
Nathan Rixham wrote: Ford, Mike wrote: -Original Message- From: Rene Veerman [mailto:rene7...@gmail.com] Sent: 27 January 2010 22:46 And if your script needs to pass large (> 5Mb) arrays around to functions, be sure to use passing-by-reference; failing to do so can double your memory requirements, possibly hitting the ini_set('memory_lmit', ??) Have you benchmarked this? PHP's copy-on-change philosophy means there shouldn't be much difference in memory terms -- so unless you actually expect to change the array's contents, you should pass by value. As proof, I constructed this little test: function test($arg, $base_mem) { echo "Additional inside func = ", memory_get_usage()-$base_mem, "\n"; } try changing this to access the array in some way such as: function test($arg, $base_mem) { foreach( $arg as $index => $value ) { } echo "Additional= ", memory_get_usage()-$base_mem, "\n"; } After array creation = 52696 Additional = 101152 Final = 117200 vs: function test(&$arg, $base_mem) After array creation = 52696 Additional = 53104 Final = 101696 there's the double memory usage I don't know what you guys are doing wrong but the following should be the correct behaviour: $value ) { $foo = $key; $foo = $value; break; } echo 'Memory: '.get_memory().' (foreach key/value access)'."\n"; } function modify_single_access( $data ) { $data[100] = str_repeat( '@', 1 ); echo 'Memory: '.get_memory().' (modify single access)'."\n"; } function modify_all_access( $data ) { for( $i = 0; $i < 1000; $i++ ) { $data[$i] = str_repeat( '@', 1 ); } echo 'Memory: '.get_memory().' (modify all access)'."\n"; } get_memory( true ); $data = array(); for( $i = 0; $i < 1000; $i++ ) { $data[$i] = str_repeat( '#', 1 ); } echo 'Memory: '.get_memory().' (data initialized)'."\n"; simple_access( $data ); foreach_value_access( $data ); foreach_key_access( $data ); modify_single_access( $data ); modify_all_access( $data ); ?> I get the following output (PHP 5.2.11 from command-line): Memory: 10160768 (data initialized) Memory: 10161008 (simple access) Memory: 10161104 (foreach value access) Memory: 10161240 (foreach key/value access) Memory: 10267312 (modify single access) Memory: 20321576 (modify all access) I don't double up on memory consumption until I force the write onto every element... this is expected because internally every array element is individually subject to the Copy-On-Write (COW) principle since each element is internally stored as a zval just like the array itself. Cheers, Rob. -- http://www.interjinn.com Application and Templating Framework for PHP -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
RE: [PHP] Pointers For Newbies, Reminders For Oldies
> -Original Message- > From: Nathan Rixham [mailto:nrix...@gmail.com] > Sent: 28 January 2010 13:43 > > Ford, Mike wrote: > >> -Original Message- > >> From: Rene Veerman [mailto:rene7...@gmail.com] > >> Sent: 27 January 2010 22:46 > >> > >> And if your script needs to pass large (> 5Mb) arrays around to > >> functions, be sure to use passing-by-reference; failing to do so > can > >> double your memory requirements, > >> possibly hitting the ini_set('memory_lmit', ??) > > > > Have you benchmarked this? PHP's copy-on-change philosophy means > there shouldn't be much difference in memory terms -- so unless you > actually expect to change the array's contents, you should pass by > value. > > > > As proof, I constructed this little test: > > > > function test($arg, $base_mem) > > { > > echo "Additional inside func = ", memory_get_usage()- > $base_mem, "\n"; > > } > > > > try changing this to access the array in some way such as: > > function test($arg, $base_mem) > { > foreach( $arg as $index => $value ) { > > } > echo "Additional= ", memory_get_usage()-$base_mem, "\n"; > } > > After array creation = 52696 > Additional = 101152 > Final = 117200 > > vs: function test(&$arg, $base_mem) > > After array creation = 52696 > Additional = 53104 > Final = 101696 > > there's the double memory usage H'mm, that's interesting! I'm not surprised about foreach causing greater memory usage, as it's defined to operate on its own copy of the array. However, when I run the same test, I get: After array creation = 546104 Additional inside func = 64504 Final = 610336 Vs After array creation = 545984 Additional inside func = 376 Final = 546360 So here I agree that the reference version is less memory intensive, but I don't see anything like a doubling of memory even for the non-reference version. I guess it depends exactly what you do inside the function/loop. I also wonder if it's different for PHP versions -- I'm on 5.2.5. I did originally do a test of straight access, such as $x = $arg[$i], with no significant effect on my results, but I didn't think about the foreach wrinkle. Out of interest, I've just run a test using a plain for loop (with a hardcoded limit, to avoid distortion caused by count()!!), which yields: Additional inside func = 328 and Additional inside func = 328 So it definitely looks like the foreach that's causing the memory bloat! This all just goes to show that you can't always second-guess the best strategy, and, unless you're really tight for some resource, you probably might just as well program in the way that feels most natural to you! Happy programming, one and all! Cheers! Mike -- Mike Ford, Electronic Information Developer, Libraries and Learning Innovation, Leeds Metropolitan University, C507, Civic Quarter Campus, Woodhouse Lane, LEEDS, LS1 3HE, United Kingdom Email: m.f...@leedsmet.ac.uk Tel: +44 113 812 4730 To view the terms under which this email is distributed, please go to http://disclaimer.leedsmet.ac.uk/email.htm -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Pointers For Newbies, Reminders For Oldies
Ford, Mike wrote: >> -Original Message- >> From: Rene Veerman [mailto:rene7...@gmail.com] >> Sent: 27 January 2010 22:46 >> >> And if your script needs to pass large (> 5Mb) arrays around to >> functions, be sure to use passing-by-reference; failing to do so can >> double your memory requirements, >> possibly hitting the ini_set('memory_lmit', ??) > > Have you benchmarked this? PHP's copy-on-change philosophy means there > shouldn't be much difference in memory terms -- so unless you actually expect > to change the array's contents, you should pass by value. > > As proof, I constructed this little test: > > function test($arg, $base_mem) > { > echo "Additional inside func = ", memory_get_usage()-$base_mem, > "\n"; > } > try changing this to access the array in some way such as: function test($arg, $base_mem) { foreach( $arg as $index => $value ) { } echo "Additional= ", memory_get_usage()-$base_mem, "\n"; } After array creation = 52696 Additional = 101152 Final = 117200 vs: function test(&$arg, $base_mem) After array creation = 52696 Additional = 53104 Final = 101696 there's the double memory usage -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Pointers For Newbies, Reminders For Oldies
Thanks for your research Mike, i'm a bit puzzled. I have a custom random-array generator that i use to fill the available memory to it's max, about 1.5G on a 2G system, then passing it to a recursive json string generator. Not passing by reference did double my memory requirements, but i've changed about 7-10 functions so i dont know which one was the pig.. On Thu, Jan 28, 2010 at 12:41 PM, Ford, Mike wrote: >> -Original Message- >> From: Rene Veerman [mailto:rene7...@gmail.com] >> Sent: 27 January 2010 22:46 >> >> And if your script needs to pass large (> 5Mb) arrays around to >> functions, be sure to use passing-by-reference; failing to do so can >> double your memory requirements, >> possibly hitting the ini_set('memory_lmit', ??) > > Have you benchmarked this? PHP's copy-on-change philosophy means there > shouldn't be much difference in memory terms -- so unless you actually expect > to change the array's contents, you should pass by value. > > As proof, I constructed this little test: > >function test($arg, $base_mem) >{ >echo "Additional inside func = ", > memory_get_usage()-$base_mem, "\n"; >} > >$mem_start = memory_get_usage(); > >$array = array_fill(1,1000,"The quick brown fox jumps over the lazy > dog"); >$mem_array = memory_get_usage(); > >echo "After array creation = ", $mem_array-$mem_start, "\n"; > >test($array, $mem_array); > >echo "Final = ", memory_get_usage()-$mem_start, "\n"; > > Which produced: > >After array creation = 546104 >Additional inside func = 208 >Final = 546312 > > Changing the function definition to have &$arg instead of just $arg changed > this to: > >After array creation = 545984 >Additional inside func = 208 >Final = 546192 > > In other words, there was no difference in the memory used to call a function > with a by-reference argument vs a by-value argument, but the by-value version > occupied an additional 120 bytes overall (which is hardly going to break the > bank!). (By varying the numbers in the array_fill(), I found some minor > variations, but nothing significant.) > > Much more interesting is adding the following line to the beginning of the > function: > >$x = count($arg); > > In this case, the by-value figures were: > >After array creation = 546104 >Additional inside func = 280 >Final = 546384 > > ... but by-reference gave: > >After array creation = 545984 >Additional inside func = 64600 >Final = 610456 > > In other words, just using count() on the array increased memory usage for > the by-*reference* version by over 60 kbytes, whereas the by-value version > only went up by 72 bytes. > > Finally, I ran a quick benchmark of runtimes for a version of the function > that just returns a single element of the array, which doesn't incur the > ballooning memory demonstrated above. For 10,000 calls to the function (in a > for loop, and averaged over several runs), the respective times were: > >By value:5.54sec >By reference:5.64sec > > Or, the by-value version was very, very slightly quicker. > > All in all, there is no evidence that passing arrays to functions by value is > inherently more expensive than by reference, and in fact in some cases it can > be significantly cheaper. Which in turn says that you should only pass > arguments by reference when you actually expect to change them, which is > after all what the by-reference operator is there for in the first place! QED. > > Cheers! > > Mike > > -- > Mike Ford, > Electronic Information Developer, Libraries and Learning Innovation, > Leeds Metropolitan University, C507, Civic Quarter Campus, > Woodhouse Lane, LEEDS, LS1 3HE, United Kingdom > Email: m.f...@leedsmet.ac.uk > Tel: +44 113 812 4730 > > > > > To view the terms under which this email is distributed, please go to > http://disclaimer.leedsmet.ac.uk/email.htm > > -- > PHP General Mailing List (http://www.php.net/) > To unsubscribe, visit: http://www.php.net/unsub.php > > -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
RE: [PHP] Pointers For Newbies, Reminders For Oldies
> -Original Message- > From: Rene Veerman [mailto:rene7...@gmail.com] > Sent: 27 January 2010 22:46 > > And if your script needs to pass large (> 5Mb) arrays around to > functions, be sure to use passing-by-reference; failing to do so can > double your memory requirements, > possibly hitting the ini_set('memory_lmit', ??) Have you benchmarked this? PHP's copy-on-change philosophy means there shouldn't be much difference in memory terms -- so unless you actually expect to change the array's contents, you should pass by value. As proof, I constructed this little test: function test($arg, $base_mem) { echo "Additional inside func = ", memory_get_usage()-$base_mem, "\n"; } $mem_start = memory_get_usage(); $array = array_fill(1,1000,"The quick brown fox jumps over the lazy dog"); $mem_array = memory_get_usage(); echo "After array creation = ", $mem_array-$mem_start, "\n"; test($array, $mem_array); echo "Final = ", memory_get_usage()-$mem_start, "\n"; Which produced: After array creation = 546104 Additional inside func = 208 Final = 546312 Changing the function definition to have &$arg instead of just $arg changed this to: After array creation = 545984 Additional inside func = 208 Final = 546192 In other words, there was no difference in the memory used to call a function with a by-reference argument vs a by-value argument, but the by-value version occupied an additional 120 bytes overall (which is hardly going to break the bank!). (By varying the numbers in the array_fill(), I found some minor variations, but nothing significant.) Much more interesting is adding the following line to the beginning of the function: $x = count($arg); In this case, the by-value figures were: After array creation = 546104 Additional inside func = 280 Final = 546384 ... but by-reference gave: After array creation = 545984 Additional inside func = 64600 Final = 610456 In other words, just using count() on the array increased memory usage for the by-*reference* version by over 60 kbytes, whereas the by-value version only went up by 72 bytes. Finally, I ran a quick benchmark of runtimes for a version of the function that just returns a single element of the array, which doesn't incur the ballooning memory demonstrated above. For 10,000 calls to the function (in a for loop, and averaged over several runs), the respective times were: By value:5.54sec By reference:5.64sec Or, the by-value version was very, very slightly quicker. All in all, there is no evidence that passing arrays to functions by value is inherently more expensive than by reference, and in fact in some cases it can be significantly cheaper. Which in turn says that you should only pass arguments by reference when you actually expect to change them, which is after all what the by-reference operator is there for in the first place! QED. Cheers! Mike -- Mike Ford, Electronic Information Developer, Libraries and Learning Innovation, Leeds Metropolitan University, C507, Civic Quarter Campus, Woodhouse Lane, LEEDS, LS1 3HE, United Kingdom Email: m.f...@leedsmet.ac.uk Tel: +44 113 812 4730 To view the terms under which this email is distributed, please go to http://disclaimer.leedsmet.ac.uk/email.htm -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Pointers For Newbies, Reminders For Oldies
Nathan Rixham wrote: > Daniel Egeberg wrote: >> On Wed, Jan 27, 2010 at 18:13, Daniel Brown wrote: >>> On Wed, Jan 27, 2010 at 12:08, Daniel Egeberg wrote: There is virtually no difference nowadays. It's a long time since anything like that has mattered. >>>Actually, that's not true enough to be dismissive. It depends on >>> several factors. >> Well, I would still say it's far too insignificant to bother with. >> > > Strangely I actually feel quite passionate about optimisation at the > procedural code level, making sure each line of code is correct and > optimised adds up to one big well optimised script / application. > > kinda like a builder saying "cement is insignificant it's the bricks > that matter", or a writer suggesting that punctuation doesn't matter any > more. > > If you took the above logic and used it in something like ActionScript > where you're code could be run at 50-60 fps (often meaning methods are > called 600-60k times a second) - little statements like that would crash > a browser and put you out of a job. > > regards :) ps: my punctuation and grammar is pants, which is why I'm not a writer. -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Pointers For Newbies, Reminders For Oldies
Richard Quadling wrote: > 2010/1/27 Richard Quadling : >> 2010/1/27 Michael A. Peters : >>> Paul M Foster wrote: "... should be obvious - but are often overlooked - points within coding practice that can cause the programmer to develop bad habits and bad code." - Dan Brown Tip #1: Don't use count() in loops unless there are very few items to count and performance doesn't matter, or the number will vary over the loop. That is, don't do this: for ($i = 0; $i < count($items); $i++) Instead, do this: $number = count($items); for ($i = 0; $i < $number; $i++) >>> Gah! >>> >>> for ($i=0;$i>> >>> is something I do all the time. >>> So the array size is being calculated each iteration? >>> >>> -- >>> PHP General Mailing List (http://www.php.net/) >>> To unsubscribe, visit: http://www.php.net/unsub.php >>> >>> >> for ($i = 0, $j = count($a) ; $i < $j ; ++$i) { >> } >> >> is a very common way to handle that. >> >> Of course... >> >> foreach(range(0, count($a)) as $i) { >> } >> >> is an alternative. >> >> You can see the effect of the counting if you replace ... >> >> count($a) >> >> with ... >> >> mycount($a) >> >> and have ... >> >> function mycount($a) { >> echo 'Counting : ', count($a), PHP_EOL; >> return count($a); >> } > > function mycount($a) { > echo 'Counting : ', count($a), PHP_EOL; > return count($a); > } > > $a = array(1,2,3,4,5,6,7,8,9,10); > > echo PHP_EOL; > for($i = 0 ; $i < mycount($a) ; ++$i) { > echo 'Traditional for() loop ', $i, PHP_EOL; > } > > echo PHP_EOL; > for($i = 0, $j = mycount($a) ; $i < $j ; ++$i) { > echo 'Modern for() loop ', $i, PHP_EOL; > } > > echo PHP_EOL; > foreach(range(0, mycount($a)) as $i) { > echo 'Ultra-modern foreach() with range() loop ', $i, PHP_EOL; > } > ?> > > outputs ... > > Counting : 10 > Traditional for() loop 0 > Counting : 10 > Traditional for() loop 1 > Counting : 10 > Traditional for() loop 2 > Counting : 10 > Traditional for() loop 3 > Counting : 10 > Traditional for() loop 4 > Counting : 10 > Traditional for() loop 5 > Counting : 10 > Traditional for() loop 6 > Counting : 10 > Traditional for() loop 7 > Counting : 10 > Traditional for() loop 8 > Counting : 10 > Traditional for() loop 9 > Counting : 10 > > Counting : 10 > Modern for() loop 0 > Modern for() loop 1 > Modern for() loop 2 > Modern for() loop 3 > Modern for() loop 4 > Modern for() loop 5 > Modern for() loop 6 > Modern for() loop 7 > Modern for() loop 8 > Modern for() loop 9 > > Counting : 10 > Ultra-modern foreach() with range() loop 0 > Ultra-modern foreach() with range() loop 1 > Ultra-modern foreach() with range() loop 2 > Ultra-modern foreach() with range() loop 3 > Ultra-modern foreach() with range() loop 4 > Ultra-modern foreach() with range() loop 5 > Ultra-modern foreach() with range() loop 6 > Ultra-modern foreach() with range() loop 7 > Ultra-modern foreach() with range() loop 8 > Ultra-modern foreach() with range() loop 9 > Ultra-modern foreach() with range() loop 10 > > > So, with the count inline, there are actually 11 calls to the count > compared to 1 in each of the other 2 scenarios. > > hate to point this out but the Ultra-modern version is counting from 0-10 rather than 0-9 or 1-10; thus it's got an extra item from somewhere :p -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Pointers For Newbies, Reminders For Oldies
Daniel Egeberg wrote: > On Wed, Jan 27, 2010 at 18:13, Daniel Brown wrote: >> On Wed, Jan 27, 2010 at 12:08, Daniel Egeberg wrote: >>> There is virtually no difference nowadays. It's a long time since >>> anything like that has mattered. >>Actually, that's not true enough to be dismissive. It depends on >> several factors. > > Well, I would still say it's far too insignificant to bother with. > Strangely I actually feel quite passionate about optimisation at the procedural code level, making sure each line of code is correct and optimised adds up to one big well optimised script / application. kinda like a builder saying "cement is insignificant it's the bricks that matter", or a writer suggesting that punctuation doesn't matter any more. If you took the above logic and used it in something like ActionScript where you're code could be run at 50-60 fps (often meaning methods are called 600-60k times a second) - little statements like that would crash a browser and put you out of a job. regards :) -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Pointers For Newbies, Reminders For Oldies
I'd like to add that when dealing with large memory structures, usually arrays, combining them is fastest when done like this: $array1 += $array2; This will not always produce correct results when dealing with arrays that contain identical keys, but for non-overlapping arrays it is far faster than array_merge() And if your script needs to pass large (> 5Mb) arrays around to functions, be sure to use passing-by-reference; failing to do so can double your memory requirements, possibly hitting the ini_set('memory_lmit', ??) $arr = array ( /* much data */ ); function workerFunc (&$data) { //work on $data, as you would normally. } workerFunc (&$arr); -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Pointers For Newbies, Reminders For Oldies
Daniel Brown wrote: On Wed, Jan 27, 2010 at 12:27, Ashley Sheridan wrote: Depends I guess on how far you need to optimise the code. I'd imagine that to something like Facebook, every split-second of optimisation is worth it, as even a 100th of a second becomes minutes of wasted time over the course of a few hours when you consider their volume of users, even with caching. Right. That, and the translation factors are the two most important things to mention. Further, translatable quotes take longer to process because they're first evaluated for things to translate. This only equals out to a few FLOPS, but when increasing by magnitude, the FLOPS are increased exponentially as well. And add on a few more FLOPS for each translation, such as escaped quotes and dollar signs. I'm pretty sure you meant linearly in the above comment. Cheers, Rob. -- http://www.interjinn.com Application and Templating Framework for PHP -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Pointers For Newbies, Reminders For Oldies
On Wed, Jan 27, 2010 at 12:27, Ashley Sheridan wrote: > > Depends I guess on how far you need to optimise the code. I'd imagine that to > something like Facebook, every split-second of optimisation is worth it, as > even a 100th of a second becomes minutes of wasted time over the course of a > few hours when you consider their volume of users, even with caching. Right. That, and the translation factors are the two most important things to mention. Further, translatable quotes take longer to process because they're first evaluated for things to translate. This only equals out to a few FLOPS, but when increasing by magnitude, the FLOPS are increased exponentially as well. And add on a few more FLOPS for each translation, such as escaped quotes and dollar signs. -- daniel.br...@parasane.net || danbr...@php.net http://www.parasane.net/ || http://www.pilotpig.net/ Looking for hosting or dedicated servers? Ask me how we can fit your budget! -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Pointers For Newbies, Reminders For Oldies
Ashley Sheridan wrote: On Wed, 2010-01-27 at 18:26 +0100, Daniel Egeberg wrote: On Wed, Jan 27, 2010 at 18:13, Daniel Brown wrote: On Wed, Jan 27, 2010 at 12:08, Daniel Egeberg wrote: There is virtually no difference nowadays. It's a long time since anything like that has mattered. Actually, that's not true enough to be dismissive. It depends on several factors. Well, I would still say it's far too insignificant to bother with. -- Daniel Egeberg Depends I guess on how far you need to optimise the code. I'd imagine that to something like Facebook, every split-second of optimisation is worth it, as even a 100th of a second becomes minutes of wasted time over the course of a few hours when you consider their volume of users, even with caching. One would expect that Facebook uses a bytecode cache... possibly one with an optimizer... the issue is very moot at that point since the difference will be optimized away at parse time. Cheers, Rob. -- http://www.interjinn.com Application and Templating Framework for PHP -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Pointers For Newbies, Reminders For Oldies
On Wed, Jan 27, 2010 at 12:26, Daniel Egeberg wrote: > > Well, I would still say it's far too insignificant to bother with. And for the most part, you'd be right but it still isn't good practice to *not* teach something strictly because it's not entirely significant. For example, polio has been all-but eradicated, but it doesn't mean that we should stop vaccinating against it. By ignoring a problem because it seems insignificant, you allow it to once again become a problem by not properly guarding against it. So even if it's just a bare mention, it's still worth that mention. Now, would I be all for a chapter on it? Probably not. ;-P -- daniel.br...@parasane.net || danbr...@php.net http://www.parasane.net/ || http://www.pilotpig.net/ Looking for hosting or dedicated servers? Ask me how we can fit your budget! -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Pointers For Newbies, Reminders For Oldies
On Wed, 2010-01-27 at 18:26 +0100, Daniel Egeberg wrote: > On Wed, Jan 27, 2010 at 18:13, Daniel Brown wrote: > > On Wed, Jan 27, 2010 at 12:08, Daniel Egeberg wrote: > >> > >> There is virtually no difference nowadays. It's a long time since > >> anything like that has mattered. > > > >Actually, that's not true enough to be dismissive. It depends on > > several factors. > > Well, I would still say it's far too insignificant to bother with. > > -- > Daniel Egeberg > Depends I guess on how far you need to optimise the code. I'd imagine that to something like Facebook, every split-second of optimisation is worth it, as even a 100th of a second becomes minutes of wasted time over the course of a few hours when you consider their volume of users, even with caching. Thanks, Ash http://www.ashleysheridan.co.uk
Re: [PHP] Pointers For Newbies, Reminders For Oldies
On Wed, Jan 27, 2010 at 18:13, Daniel Brown wrote: > On Wed, Jan 27, 2010 at 12:08, Daniel Egeberg wrote: >> >> There is virtually no difference nowadays. It's a long time since >> anything like that has mattered. > > Actually, that's not true enough to be dismissive. It depends on > several factors. Well, I would still say it's far too insignificant to bother with. -- Daniel Egeberg -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Pointers For Newbies, Reminders For Oldies
On Wed, Jan 27, 2010 at 12:08, Daniel Egeberg wrote: > > There is virtually no difference nowadays. It's a long time since > anything like that has mattered. Actually, that's not true enough to be dismissive. It depends on several factors. -- daniel.br...@parasane.net || danbr...@php.net http://www.parasane.net/ || http://www.pilotpig.net/ Looking for hosting or dedicated servers? Ask me how we can fit your budget! -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Pointers For Newbies, Reminders For Oldies
On Wed, Jan 27, 2010 at 16:44, Ashley Sheridan wrote: > What about using the right type of quotation marks for output: > > I use double quotes(") if I expect to output variables within the > string, and single quotes when it's just a simple string. > > It's only a general rule of thumb and shouldn't be adhered to > absolutely, but I remember a thread a while back that showed the speed > differences between the two because of the extra parsing PHP does on > double quoted strings. There is virtually no difference nowadays. It's a long time since anything like that has mattered. -- Daniel Egeberg -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Pointers For Newbies, Reminders For Oldies
2010/1/27 Richard Quadling : > 2010/1/27 Michael A. Peters : >> Paul M Foster wrote: >>> >>> "... should be obvious - but are often overlooked - points within coding >>> practice that can cause the programmer to develop bad habits and bad >>> code." - Dan Brown >>> >>> Tip #1: >>> >>> Don't use count() in loops unless there are very few items to count and >>> performance doesn't matter, or the number will vary over the loop. That >>> is, don't do this: >>> >>> for ($i = 0; $i < count($items); $i++) >>> >>> Instead, do this: >>> >>> $number = count($items); >>> for ($i = 0; $i < $number; $i++) >> >> Gah! >> >> for ($i=0;$i> >> is something I do all the time. >> So the array size is being calculated each iteration? >> >> -- >> PHP General Mailing List (http://www.php.net/) >> To unsubscribe, visit: http://www.php.net/unsub.php >> >> > > for ($i = 0, $j = count($a) ; $i < $j ; ++$i) { > } > > is a very common way to handle that. > > Of course... > > foreach(range(0, count($a)) as $i) { > } > > is an alternative. > > You can see the effect of the counting if you replace ... > > count($a) > > with ... > > mycount($a) > > and have ... > > function mycount($a) { > echo 'Counting : ', count($a), PHP_EOL; > return count($a); > } outputs ... Counting : 10 Traditional for() loop 0 Counting : 10 Traditional for() loop 1 Counting : 10 Traditional for() loop 2 Counting : 10 Traditional for() loop 3 Counting : 10 Traditional for() loop 4 Counting : 10 Traditional for() loop 5 Counting : 10 Traditional for() loop 6 Counting : 10 Traditional for() loop 7 Counting : 10 Traditional for() loop 8 Counting : 10 Traditional for() loop 9 Counting : 10 Counting : 10 Modern for() loop 0 Modern for() loop 1 Modern for() loop 2 Modern for() loop 3 Modern for() loop 4 Modern for() loop 5 Modern for() loop 6 Modern for() loop 7 Modern for() loop 8 Modern for() loop 9 Counting : 10 Ultra-modern foreach() with range() loop 0 Ultra-modern foreach() with range() loop 1 Ultra-modern foreach() with range() loop 2 Ultra-modern foreach() with range() loop 3 Ultra-modern foreach() with range() loop 4 Ultra-modern foreach() with range() loop 5 Ultra-modern foreach() with range() loop 6 Ultra-modern foreach() with range() loop 7 Ultra-modern foreach() with range() loop 8 Ultra-modern foreach() with range() loop 9 Ultra-modern foreach() with range() loop 10 So, with the count inline, there are actually 11 calls to the count compared to 1 in each of the other 2 scenarios. -- - Richard Quadling "Standing on the shoulders of some very clever giants!" EE : http://www.experts-exchange.com/M_248814.html EE4Free : http://www.experts-exchange.com/becomeAnExpert.jsp Zend Certified Engineer : http://zend.com/zce.php?c=ZEND002498&r=213474731 ZOPA : http://uk.zopa.com/member/RQuadling -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Pointers For Newbies, Reminders For Oldies
Richard Quadling wrote: for ($i = 0, $j = count($a) ; $i < $j ; ++$i) { } is a very common way to handle that. Thanks! -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Pointers For Newbies, Reminders For Oldies
2010/1/27 Michael A. Peters : > Paul M Foster wrote: >> >> "... should be obvious - but are often overlooked - points within coding >> practice that can cause the programmer to develop bad habits and bad >> code." - Dan Brown >> >> Tip #1: >> >> Don't use count() in loops unless there are very few items to count and >> performance doesn't matter, or the number will vary over the loop. That >> is, don't do this: >> >> for ($i = 0; $i < count($items); $i++) >> >> Instead, do this: >> >> $number = count($items); >> for ($i = 0; $i < $number; $i++) > > Gah! > > for ($i=0;$i > is something I do all the time. > So the array size is being calculated each iteration? > > -- > PHP General Mailing List (http://www.php.net/) > To unsubscribe, visit: http://www.php.net/unsub.php > > for ($i = 0, $j = count($a) ; $i < $j ; ++$i) { } is a very common way to handle that. Of course... foreach(range(0, count($a)) as $i) { } is an alternative. You can see the effect of the counting if you replace ... count($a) with ... mycount($a) and have ... function mycount($a) { echo 'Counting : ', count($a), PHP_EOL; return count($a); } -- - Richard Quadling "Standing on the shoulders of some very clever giants!" EE : http://www.experts-exchange.com/M_248814.html EE4Free : http://www.experts-exchange.com/becomeAnExpert.jsp Zend Certified Engineer : http://zend.com/zce.php?c=ZEND002498&r=213474731 ZOPA : http://uk.zopa.com/member/RQuadling -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Pointers For Newbies, Reminders For Oldies
On Thu, 2010-01-28 at 00:08 +0800, Eric Lee wrote: > On Wed, Jan 27, 2010 at 11:44 PM, Ashley Sheridan > wrote: > > > On Wed, 2010-01-27 at 10:42 -0500, Paul M Foster wrote: > > > > > "... should be obvious - but are often overlooked - points within coding > > > practice that can cause the programmer to develop bad habits and bad > > > code." - Dan Brown > > > > > > Tip #1: > > > > > > Don't use count() in loops unless there are very few items to count and > > > performance doesn't matter, or the number will vary over the loop. That > > > is, don't do this: > > > > > > for ($i = 0; $i < count($items); $i++) > > > > > > Instead, do this: > > > > > > $number = count($items); > > > for ($i = 0; $i < $number; $i++) > > > > > > Reason: when you use the count() call at the top of the loop, it will > > > re-evaluate the number of items each time it's called, which usually > > > isn't necessary and adds time. Instead, work out the number of items > > > before going into the loop and simply refer to that for the number of > > > items in controlling the loop. > > > > > > Paul > > > > > > -- > > > Paul M. Foster > > > > > > > > > What about using the right type of quotation marks for output: > > > > I use double quotes(") if I expect to output variables within the > > string, and single quotes when it's just a simple string. > > > > It's only a general rule of thumb and shouldn't be adhered to > > absolutely, but I remember a thread a while back that showed the speed > > differences between the two because of the extra parsing PHP does on > > double quoted strings. > > > > > That should be on the stackoverflow.com > It compare the string parsing with or without variables embeded > and the important of comma operator when ` echo ` data > > use > echo 'something', 'other' > > but not > echo 'something' . 'other' > > > Eric, > > > > Thanks, > > Ash > > http://www.ashleysheridan.co.uk > > > > > > There is a big difference between using a comma and a period. A period (.) actually concatenates the strings, whereas a comma only adds it to the echo stream. So, if you were trying to assign the joining of the two strings to a variable, you would have to use a period, as the comma would throw a syntax error. Thanks, Ash http://www.ashleysheridan.co.uk
Re: [PHP] Pointers For Newbies, Reminders For Oldies
On Wed, Jan 27, 2010 at 11:44 PM, Ashley Sheridan wrote: > On Wed, 2010-01-27 at 10:42 -0500, Paul M Foster wrote: > > > "... should be obvious - but are often overlooked - points within coding > > practice that can cause the programmer to develop bad habits and bad > > code." - Dan Brown > > > > Tip #1: > > > > Don't use count() in loops unless there are very few items to count and > > performance doesn't matter, or the number will vary over the loop. That > > is, don't do this: > > > > for ($i = 0; $i < count($items); $i++) > > > > Instead, do this: > > > > $number = count($items); > > for ($i = 0; $i < $number; $i++) > > > > Reason: when you use the count() call at the top of the loop, it will > > re-evaluate the number of items each time it's called, which usually > > isn't necessary and adds time. Instead, work out the number of items > > before going into the loop and simply refer to that for the number of > > items in controlling the loop. > > > > Paul > > > > -- > > Paul M. Foster > > > > > What about using the right type of quotation marks for output: > > I use double quotes(") if I expect to output variables within the > string, and single quotes when it's just a simple string. > > It's only a general rule of thumb and shouldn't be adhered to > absolutely, but I remember a thread a while back that showed the speed > differences between the two because of the extra parsing PHP does on > double quoted strings. > > That should be on the stackoverflow.com It compare the string parsing with or without variables embeded and the important of comma operator when ` echo ` data use echo 'something', 'other' but not echo 'something' . 'other' Eric, > Thanks, > Ash > http://www.ashleysheridan.co.uk > > >
Re: [PHP] Pointers For Newbies, Reminders For Oldies
On Wed, 2010-01-27 at 08:01 -0800, Michael A. Peters wrote: > Paul M Foster wrote: > > "... should be obvious - but are often overlooked - points within coding > > practice that can cause the programmer to develop bad habits and bad > > code." - Dan Brown > > > > Tip #1: > > > > Don't use count() in loops unless there are very few items to count and > > performance doesn't matter, or the number will vary over the loop. That > > is, don't do this: > > > > for ($i = 0; $i < count($items); $i++) > > > > Instead, do this: > > > > $number = count($items); > > for ($i = 0; $i < $number; $i++) > > Gah! > > for ($i=0;$i > is something I do all the time. > So the array size is being calculated each iteration? > Yeah, the condition is evaluated once for each cycle of the loop. I use the count() a lot myself tbh, but I don't often have the call to work with massive data sets and huge loops. Thanks, Ash http://www.ashleysheridan.co.uk
Re: [PHP] Pointers For Newbies, Reminders For Oldies
Paul M Foster wrote: "... should be obvious - but are often overlooked - points within coding practice that can cause the programmer to develop bad habits and bad code." - Dan Brown Tip #1: Don't use count() in loops unless there are very few items to count and performance doesn't matter, or the number will vary over the loop. That is, don't do this: for ($i = 0; $i < count($items); $i++) Instead, do this: $number = count($items); for ($i = 0; $i < $number; $i++) Gah! for ($i=0;$ihttp://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Pointers For Newbies, Reminders For Oldies
On Wed, 2010-01-27 at 10:42 -0500, Paul M Foster wrote: > "... should be obvious - but are often overlooked - points within coding > practice that can cause the programmer to develop bad habits and bad > code." - Dan Brown > > Tip #1: > > Don't use count() in loops unless there are very few items to count and > performance doesn't matter, or the number will vary over the loop. That > is, don't do this: > > for ($i = 0; $i < count($items); $i++) > > Instead, do this: > > $number = count($items); > for ($i = 0; $i < $number; $i++) > > Reason: when you use the count() call at the top of the loop, it will > re-evaluate the number of items each time it's called, which usually > isn't necessary and adds time. Instead, work out the number of items > before going into the loop and simply refer to that for the number of > items in controlling the loop. > > Paul > > -- > Paul M. Foster > What about using the right type of quotation marks for output: I use double quotes(") if I expect to output variables within the string, and single quotes when it's just a simple string. It's only a general rule of thumb and shouldn't be adhered to absolutely, but I remember a thread a while back that showed the speed differences between the two because of the extra parsing PHP does on double quoted strings. Thanks, Ash http://www.ashleysheridan.co.uk
[PHP] Pointers For Newbies, Reminders For Oldies
"... should be obvious - but are often overlooked - points within coding practice that can cause the programmer to develop bad habits and bad code." - Dan Brown Tip #1: Don't use count() in loops unless there are very few items to count and performance doesn't matter, or the number will vary over the loop. That is, don't do this: for ($i = 0; $i < count($items); $i++) Instead, do this: $number = count($items); for ($i = 0; $i < $number; $i++) Reason: when you use the count() call at the top of the loop, it will re-evaluate the number of items each time it's called, which usually isn't necessary and adds time. Instead, work out the number of items before going into the loop and simply refer to that for the number of items in controlling the loop. Paul -- Paul M. Foster -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php