views:

39

answers:

3

What is quicker, for camelCase to underscores; using preg_replace() or using ord() ?

My guess is the method using ord will be quicker, since preg_replace can do much more then needed.

<?php
function __autoload($class_name){
    $name = strtolower(preg_replace('/([a-z])([A-Z])/', '$1_$2', $class_name));
    require_once("some_dir/".$name.".php");
}
?>

OR

<?php
function __autoload($class_name){
// lowercase first letter
$class_name[0] = strtolower($class_name[0]);

$len = strlen($class_name);
for ($i = 0; $i < $len; ++$i) {
    // see if we have an uppercase character and replace
    if (ord($class_name[$i]) > ord('A') && ord($class_name[$i]) < ord('Z')) {
        $class_name[$i] = '_' . strtolower($class_name[$i]);
        // increase length of class and position
        ++$len;
        ++$i;
    }
}

return $class_name;
}
?>

disclaimer -- code examples taken from StackOverflowQuestion 1589468.

edit, after jensgram's array-suggestion and finding array_splice i have come up with the following :

<?php
function __autoload ($string)// actually, function camel2underscore
{
$string  =  str_split($string);
$pos     =  count( $string );
while ( --$pos > 0 )
{
    $lower  =  strtolower( $string[ $pos ] );
    if ( $string[ $pos ] === $lower )
    {
        // assuming most letters will be underscore this should be improvement
        continue;
    }
    unset( $string[ $pos ] );
    array_splice( $string , $pos , 0 , array( '_' , $lower ) );
}
$string  =  implode( '' , $string );
return $string;
}
// $pos could be avoided by using the array key, something i might look into later on.
?>

When i will be testing these methods i will add this one but feel free to tell me your results at anytime ;p

+1  A: 

i think (and i'm pretty much sure) that the preg_replace method will be faster - but if you want to know, why dont you do a little benchmark calling both functions 100000 times and measure the time?

oezi
you are absolutely right!
etbal
A: 

(Not an answer but too long to be a comment - will CW)

If you're going to compare, you should at least optimize a little on the ord() version.

$len = strlen($class_name);
$ordCurr = null;
$ordA = ord('A');
$ordZ = ord('Z');
for ($i = 0; $i < $len; ++$i) {
    $ordCurr = ord($class_name[$i]);
    // see if we have an uppercase character and replace
    if ($ordCurr >= $ordA && $ordCurr <= $ordZ) {
        $class_name[$i] = '_' . strtolower($class_name[$i]);
        // increase length of class and position
        ++$len;
        ++$i;
    }
}

Also, pushing the name onto a stack (an array) and joining at the end might prove more efficient than string concatenation.

BUT Is this worth the optimization / profiling in the first place?

jensgram
more useful as well, `$class_name[$i] = '_' . strtolower($class_name[$i]);` does not work as expected...
immeëmosol
@immeëmosol No, at least you should maintain a new string for the result. I didn't really dig into the code - just wanted to illustrate some simple techniques :)
jensgram
your array idea got me working on a different implementation. at a certain point i will be testing them for speed( by the way, i don't like comments without linebreaks :s ). i'll put the code in a comment because of that.
immeëmosol
A: 

If all you want to do is convert camel case to underscores, you can probably write a more efficient function to do so than either ord or preg_replace in less time than it takes to profile them.

Sam Dufel
i hopefully did with the last added method, still will profile them on some terribly dreadful sunny day though.
immeëmosol