2

I have recently created a php extension with PHPCPP - C++ library for developing PHP extensions and was expecting a performance boost, however instead of seeing a boost i m only seeing degradation in performance. I believe i'm doing something incorrectly and maybe somebody may spot why is this happening?

Here is a C++ code:

#include <phpcpp.h>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <string> 
#include <regex>
#include <stdlib.h>     /* atof,strtod */
#include <cstddef>        // std::size_t
#include <sstream>
#include <vector>
#include <boost/algorithm/string.hpp> // include Boost, a C++ library
#include <boost/regex.hpp>

using namespace std;
Php::Value test_function(Php::Parameters &params)
{
    double a = params[0];
    double b = params[1];

    return (a + b) * (a - b) / 100;
}

/**
*  Switch to C context, because the Zend engine expects get get_module()
*  to have a C style function signature
*/
extern "C" {
    /**
    *  Startup function that is automatically called by the Zend engine
    *  when PHP starts, and that should return the extension details
    *  @return void*
    */
    PHPCPP_EXPORT void *get_module()
    {
        // the extension object
        static Php::Extension extension("test_extension", "1.0");

        // add functions so that they can be called from PHP scripts

        extension.add("test_function", test_function, {
            Php::ByVal("a", Php::Type::Float,true),
            Php::ByVal("b", Php::Type::Float,true)
        });
        // return the extension details
        return extension;
    }
}

Here is the command line extension compilation:

[root@test test_extension]# make
g++ -Wall -c -O2 -std=c++11 -fpic -o main.o main.cpp
g++ -shared -o test_extension.so main.o -lphpcpp
[root@test test_extension]# make install
cp -f test_extension.so /usr/lib64/php/modules
cp -f test_extension.ini /etc/php.d

Here is my simple test:

<?php
//function written in php
function local_test_function($a,$b){
    $res = ($a + $b) * ($a - $b) / 100;
    return $res;
}

$output = '';

//local php function test

    $start_time = microtime(true);
    $output.= "<br> test_function local: " . local_test_function(123.4,12.5);
    $end_time = microtime(true);
    $duration = $end_time - $start_time;
    $duration = number_format($duration,20);
    $output.=", Duration: ".$duration.'<br>';

// function written in c++

    $start_time = microtime(true);
    $output.= "function written in c++: " . test_function(123.4,12.5);

    $end_time = microtime(true);
    $duration = $end_time - $start_time;
    $duration = number_format($duration,20);
    $output.=", Duration: ".$duration . '<br>';

?>

The results are:

test_function local result: 150.7131, Duration: 0.00000715255737304688
function written in c++ result: 150.7131, Duration: 0.00003004074096679688

the conclusion PHP function written in C++ is 4 times slower. Can someone tell why? And is there a way to improve my code in C++?

anonymous007
  • 319
  • 1
  • 3
  • 12
  • 7
    I suspect its not the C++ code that's slow but the overhead of calling the native function. Can you try with a function that has more code in it? – Borgleader Aug 09 '17 at 18:29
  • 2
    Your testing code is pointless. You need to run multiple iterations (at least 1000000) using random inputs and remove string concatenation as it most likely takes more time than function call. – user7860670 Aug 09 '17 at 19:00
  • 1
    I suggest calculating pi for some thousand poitions. – Hannes Hauptmann Aug 09 '17 at 19:03

1 Answers1

1

UPDATE and ANSWER

as suggested i'm trying to test with a more complex function to see if overhead is causing C++ function to be slower

i have modified existing "test_function" + added another function "test_function_inner" and declared it.

double test_function_inner(double a, double b);

      Php::Value test_function(Php::Parameters &params)
    {
        double a = params[0];
        double b = params[1];
        double res = 0.0;
        int i = 100;
        while (i > 0) {
            res = res + test_function_inner(a, b);
            --i;
        }

        return res;
    }
    double test_function_inner(double a, double b) {
        double res = 0.0;
        while (b > a) {
            res = res + (a + b) * (a - b) / 100;
            b = b - 1;
        }
        return res;
    }

Testing:

 <?php
    $output = '';

    //local php function test

        $start_time = microtime(true);
        $output.= "<br> test_function local: " . local_test_function(123.4,1200000.5);
        $end_time = microtime(true);
        $duration = $end_time - $start_time;
        $duration = number_format($duration,20);
        $output.=", Duration: ".$duration.'<br>';

    // function written in c++

        $start_time = microtime(true);
        $output.= "function written in c++: " . test_function(123.4,1200000.5);

        $end_time = microtime(true);
        $duration = $end_time - $start_time;
        $duration = number_format($duration,20);
        $output.=", Duration: ".$duration . '<br>';
    ?>

results:

test_function local result: -5.7600142172989E+17, Duration: 9.23940896987915039062

function written in c++ result: -5.7600142172989E+17, Duration: 0.72759604454040527344

CONCLUSION it was overhead caused by initial function call as suggested , and small operations and calculations doesn't worth putting into separate functions in the extension as it wouldn't boost the application but instead would cause negative effect on performance.

anonymous007
  • 319
  • 1
  • 3
  • 12