• 技术文章 >后端开发 >php教程

    面试官:列举几种PHP拓展的实现手段及其性能比较?

    藏色散人藏色散人2022-03-28 14:00:02转载363
    关于 PHP 扩展的几种实现手段

    1.php 原生扩展开发 c 语言,注:【ext_skel.php】脚本创建

    2.zephir

    3.php-cpp

    4.php-x

    5.cgo

    等。。。不限上面几种方式。

    围绕【zephir,cgo,PHP 开启 JIT】4 种模式下,通过斐波那契数列计算性能,来查看运行效果。

    zephir 代码生成扩展

    //Main 类
    final class Zimuge
    {
      public static function calcFibonacci(int i){
          if (i < 2) {
              return i;
          }
          return self::calcFibonacci(i - 1) + self::calcFibonacci(i - 2);
      }
    编译安装
    zephir build

    cgo 代码生成扩展

    package main
    /*
    #ifdef HAVE_CONFIG_H
    #include "config.h"
    #endif
    #include "php.h"
    #include "php_ini.h"
    #include "ext/standard/info.h"
    static int le_go2php;
    PHP_MINIT_FUNCTION(go2php)
    {
        return SUCCESS;
    }
    PHP_MSHUTDOWN_FUNCTION(go2php)
    {
        return SUCCESS;
    }
    PHP_RINIT_FUNCTION(go2php)
    {
        return SUCCESS;
    }
    PHP_RSHUTDOWN_FUNCTION(go2php)
    {
        return SUCCESS;
    }
    PHP_MINFO_FUNCTION(go2php)
    {
        php_info_print_table_start();
        php_info_print_table_header(2, "go2php support", "enabled");
        php_info_print_table_end();
    }
    PHP_FUNCTION(go2php_print)
    {
        zend_long a,b;
        ZEND_PARSE_PARAMETERS_START(1, 1)
            Z_PARAM_LONG(a)
        ZEND_PARSE_PARAMETERS_END();
        b = calcFib(a);
        RETURN_LONG(b);
    }
    ZEND_BEGIN_ARG_INFO(null, 0)
    ZEND_END_ARG_INFO()
    const zend_function_entry go2php_functions[] = {
        PHP_FE(go2php_print, null)
        PHP_FE_END
    };
    zend_module_entry go2php_module_entry = {
        STANDARD_MODULE_HEADER,
        "go2php",
        go2php_functions,
        PHP_MINIT(go2php),
        PHP_MSHUTDOWN(go2php),
        PHP_RINIT(go2php),
        PHP_RSHUTDOWN(go2php),
        PHP_MINFO(go2php),
        "0.1.0",
        STANDARD_MODULE_PROPERTIES
    };
    #ifdef COMPILE_DL_GO2PHP
    ZEND_GET_MODULE(go2php)
    #endif
    */
    import "C"
    func main() {}
    package main
    import "C"
    //export calcFib
    func calcFib(i int) int {
        if i < 2 {
            return i
        }
        return calcFib(i-1)+calcFib(i-2)
    }

    编译&链接

    CGO_CFLAGS="-g \
    -I`/root/download/php8/bin/php-config --include-dir` \
    -I`/root/download/php8/bin/php-config --include-dir`/main \
    -I`/root/download/php8/bin/php-config --include-dir`/TSRM \
    -I`/root/download/php8/bin/php-config --include-dir`/Zend \
    -I`/root/download/php8/bin/php-config --include-dir`/ext \
    -I`/root/download/php8/bin/php-config --include-dir`/ext/date/lib \
    -DHAVE_CONFIG_H" CGO_LDFLAGS="-Wl,--export-dynamic -Wl,--unresolved-symbols=ignore-all" go build -p 1 -gcflags "-l" -buildmode=c-shared -o go2php.so

    测试用 php 脚本代码

    <?php
    const COUNT = 30;
    function calcFibonacci(int $i): int {
        if ($i < 2) {
            return $i;
        }
        return calcFibonacci($i - 1) + calcFibonacci($i - 2);
    }
    // CGO 速度
    $startTime = microtime(true);
    for($i = 1; $i <= COUNT; $i++) {
        if($i != COUNT) {
            go2php_print($i);
        }else {
            echo go2php_print($i)."\n";
        }
    }
    $time = microtime(true) - $startTime;
    echo "CGO: {$time} 秒\n";
    //zephir 速度
    $startTime = microtime(true);
    for($i = 1; $i <= COUNT; $i++) {
        if($i != COUNT) {
            Lsz\Zimuge::calcFibonacci($i);
        }else {
            echo Lsz\Zimuge::calcFibonacci($i)."\n";
        }
    }
    $time = microtime(true) - $startTime;
    echo "zephir: {$time} 秒\n";
    // PHP JIT 速度
    $startTime = microtime(true);
    for($i = 1; $i <= COUNT; $i++) {
        if($i != COUNT) {
            calcFibonacci($i);
        }else {
            echo calcFibonacci($i)."\n";
        }
    }
    $time = microtime(true) - $startTime;
    echo "PHP: {$time} 秒\n";

    不使用 PHP JIT 的情况下测试

    php test.php
    ->执行结果取一个平均
    832040
    CGO: 0.059875011444092 秒
    832040
    zephir: 8.5679790973663 秒
    832040
    PHP: 0.75995492935181 秒

    使用 PHP JIT 的情况下测试

    php -dopcache.enable_cli=1 -dopcache.jit_buffer_size=100M test.php 
    ->执行结果取一个平均
    832040
    CGO: 0.046900987625122 秒
    832040
    zephir: 5.5882248878479 秒
    832040
    PHP: 0.10621190071106 秒

    cgo 和 zephir 编译后的 so文件,通过php.ini 引入进来

    执行测试脚本需要保证so正确读取进来。

    命令 php -m 或者 php --ri xx.so 进行确认。

    [PHP Modules]
    Core
    ctype
    curl
    date
    dom
    FFI
    fileinfo
    filter
    gd
    go2php
    hash
    iconv
    json
    libxml
    lsz
    mbstring
    mysqlnd
    openssl
    pcre
    PDO
    pdo_mysql
    pdo_sqlite
    Phar
    posix
    redis
    Reflection
    session
    SimpleXML
    SPL
    sqlite3
    standard
    swoole
    tokenizer
    xml
    xmlreader
    xmlwriter
    yaf
    Zend OPcache
    zephir_parser
    zimuge
    [Zend Modules]
    Zend OPcache

    使用PHP版本

    php -v
    PHP 8.1.3 (cli) (built: Feb 27 2022 19:40:08) (NTS)
    Copyright (c) The PHP Group
    Zend Engine v4.1.3, Copyright (c) Zend Technologies
        with Zend OPcache v8.1.3, Copyright (c), by Zend Technologies

    结论:

    JIT 能提高 php 的性能。

    想学习 go 又不想放弃 php 可以用玩下 CGO。

    zephir 虽然计算性能不太好,但是写 PHP 扩展实现起来比较简单。

    推荐学习:《PHP视频教程

    以上就是面试官:列举几种PHP拓展的实现手段及其性能比较?的详细内容,更多请关注php中文网其它相关文章!

    声明:本文转载于:learnku,如有侵犯,请联系admin@php.cn删除
    专题推荐:PHP扩展
    上一篇:归纳整理39道PHP面试题(总结分享) 下一篇:一起来分析为什么不能在PHP中使用泛型
    PHP编程就业班

    相关文章推荐

    • 如何用composer开发自己的php扩展包• 关于ThinkPHP扩展配置注意事项• 宝塔面板之安装第三方PHP扩展示例• 如何动态查看及加载PHP扩展• 如何解决“您的服务器没有安装这个php扩展”问题

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网