面试官:列举几种PHP拓展的实现手段及其性能比较?
3547
关于 PHP 扩展的几种实现手段
1.php 原生扩展开发 c 语言,注:【ext_skel.php】脚本创建
2.zephir
3.php-cpp
4.php-x
5.cgo
封装 zendapi 模式
CGO 嵌套 C 和 GO 代码,用 GO 去编译了 php 扩展骨架和 GO 的具体实现
等。。。不限上面几种方式。
围绕【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 扩展实现起来比较简单。
本文网址:https://www.zztuku.com/index.php/detail-11396.html
站长图库 - 面试官:列举几种PHP拓展的实现手段及其性能比较?
申明:本文转载于《learnku》,如有侵犯,请 联系我们 删除。
您还没有登录,请 登录 后发表评论!
提示:请勿发布广告垃圾评论,否则封号处理!!