Factorials in C

Back in the Functions chapter we looked at how PHP to calculate factorials, but now we're going to convert that into C code as a PHP extension. Although calculating factorials is a moderately computationally expensive operation, it also requires lots of function calls - we should be able to expect a substantial speed boost by converting PHP to C, but not much more than about 7x.

The interesting thing about factorials, which is why I wanted to demonstrate their use, is that they require two functions: one for PHP users and one for internal, recursive calling. Unsurprisingly, this is very easy to do in PHP, so let's jump right in with a new function: hello_factorial(). You need to add the PHP_FUNCTION() macro to php_hello.h and the PHP_FE() macro to hello.c. Once you've done that, add these two functions beneath hello_print() in hello.c:

double do_hello_factorial(double val) {
    if (val <= 1) return 1;   
    return val * do_hello_factorial(val - 1);
}

/* {{{ proto int hello_factorial(float num)
*   Print the factorial of a given number */
PHP_FUNCTION(hello_factorial)
{
    double val;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &val) == FAILURE) {
        return;
    }

    RETURN_DOUBLE(do_hello_factorial(val));
}
/* }}} */

The first function is internal, and so is a standard C function. As you can see, it takes a double (a large floating-point value) and recurses on itself to figure out the factorial. The main point of interest, though, is the hello_factorial() function, as it uses zend_parse_parameters() to get a double ("d") from the parameters inputted by the script.

It also uses another special macro, RETURN_DOUBLE(), that sets the return value for this function. The line in the example sets the return value to the return value from do_hello_factorial(), and also passes in the double we received from the script. What this means is, "calculate the factorial of this number, then set the result to the return value.

Go ahead and build the new extension, and try a simple benchmark to see the speed difference between PHP and C code for factorials. In my tests I found the C version to be approximately 8.5 times faster than the PHP code - not bad!

 

Want to learn PHP 7?

Hacking with PHP has been fully updated for PHP 7, and is now available as a downloadable PDF. Get over 1200 pages of hands-on PHP learning today!

If this was helpful, please take a moment to tell others about Hacking with PHP by tweeting about it!

Next chapter: Extensions Conclusion >>

Previous chapter: C Hello World v2

Jump to:

 

Home: Table of Contents

Copyright ©2015 Paul Hudson. Follow me: @twostraws.