如何用 Rust 来为 PHP 助力
上周,一篇关于《PHP 兼 Zend 联合创始人 Zeev Suraski 宣布从 Zend 离职》的文章在中国程序员中炸开了锅。文章中的Zend创始人离职可谓引起轩然大波,各种对PHP不友好的声音也被传递了出来。虽然来自中国的PHP核心开发者鸟哥发声,但许多程序员对PHP的态度并不是很乐观。
作为我在Web领域的入门语言,对PHP的感情犹如初恋一般美好。但伴随着近几年来大家对PHP各种调侃、讽刺,加上新语言Go、Rust、Javascript等强势崛起。似乎让“我是一名PHP程序员”变得底气很不足。来源于Web、辉煌于Web、受限于Web,不得不说,这让脚本语言PHP陷入了困境,因为Web已经不再是那个靠渲染网页的PC时代,虽然目前有Swoole这样优秀的异步方案,但也很难让我对PHP提起足够的兴趣。
Rust作为近几年来逐步流行的新兴语言,凭借安全、高效、可靠,开始进入了人们的视野。周末,重拾起了PHP,想看看是否能够在PHP和Rust之间擦出一点点火花。当然,只是出于个人兴趣做的一些实验,这并不能为两个优秀的语言带来什么改变。但我想,至少能够让大家对PHP和Rust有更多的了解。
PHP7.4中的FFI
起初,PHP7.4中的新特性FFI引起我很大的兴趣,因为在很多语言中已经拥有了这样的特性,例如:Python、NodeJS、Ruby等,PHP首次的引入,让我觉得PHP团队正在朝着这方面进行努力。
我首先采用Rust编写了一个Fibonacci斐波那契数列,这里实现了一个简单的计算函数,我将他导出为动态链接库,以供PHP的FFI调用。
#[no_mangle] pub extern fn fib(n: i32) -> i32 { return match n { 1 | 2 => 1, n => fib(n - 1) + fib(n - 2) } }
编写完成后,我尝试在PHP的FFI中进行调用,为了想对比下性能,我同时编写了一个PHP的函数:
// 一个PHP的fib函数 function fib($n) { if ($n === 1 || $n === 2) { return 1; } else { return fib($n-1) + fib($n-2); } }
接下来,我在PHP中调用他们,为了能够看出性能差异,我将调用1000000次:
// release模式 $ffiRelease = FFI::cdef( "int32_t fib(int32_t n);", "r2p-fib/target/release/libr2pfib.$libExtension"); $time_start = microtime(true); for ($i=0; $i < 10000000; $i++) { $v = $ffiRelease->fib(12); } echo '[Rust]Release执行时间:' . (microtime(true) - $time_start).PHP_EOL;
从测试结果来看,Rust的FFI结果是让人惊喜的。
PHP的计算耗时30秒以上,Rust仅仅用了6秒。
当我为此欣喜若狂的时候,我又尝试了下PHP的FFI调用生成字符串,在PHP中是类似这样一个方法:
function text_generate($num) { $result = "💣"; $result .= str_repeat("na ",$num); $result .= "Batman! 💣"; return $result; }
结果Rust由于在PHP的FFI中间字符串转换的损耗,性能并没有达到预想那样。
PHP扩展调用Rust动态库
因为第一个操作,让我想到了FFI在多次调用性能损耗是很大的,这时我想实现在PHP扩展中来调用Rust动态库。
同时为了对比,我编写一个C的Fib函数进行比较。
我创建了一个名为rust
的PHP扩展,完成了关于我们上面编写的Rust函数的调用。
ZEND_BEGIN_ARG_INFO(arginfo_rust_fib, 0) ZEND_ARG_INFO(0, number) ZEND_END_ARG_INFO() /* {{{ int rust_fib( [ int $var ] ) */ PHP_FUNCTION(rust_fib) { zend_long number = 0; zend_long result = 0; ZEND_PARSE_PARAMETERS_START(0, 1) Z_PARAM_OPTIONAL Z_PARAM_LONG(number) ZEND_PARSE_PARAMETERS_END(); if (number == 0) { RETURN_LONG(result); } else { result = fib(number); RETURN_LONG(result); } } /* }}}*/
结果同样让我惊喜,没有了FFI,它确实提升了20%左右的性能。但很明显,它的实现复杂度更高了。
采用Rust编写PHP扩展
将PHP的Zend API结构导出,直接在Rust中实现PHP模块的编写。虽然自己没有足够的精力去做这样的尝试,但我觉得这是一个可行的方法。我想在未来的时间内完成这样的尝试。
总结
虽然影响PHP更好的发展的主要因素并不是性能,尽管本篇只是从性能提升入手对PHP进行了测试,但我觉得,作为一个拥有如此庞大开发群体的Web语言,也是时候需要跟Go、Rust、Node这些新兴语言学习了,建立并不局限于Web领域的新的生态体系,大胆的去做一些新的尝试,让PHP不再是“世界第一语言”。
本文完整测试代码及结果请参考:https://github.com/llgoer/php-ffi-rust/
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
CapitalOne 和 GitHub 因数据泄露事件遭遇集体诉讼
来自thehill 的消息:CapitalOne 和 GitHub 因近期的数据泄露事件而遭遇集体诉讼,事件导致 CapitalOne 泄露超过 1 亿条客户数据。 Tycko&Zavareei LLP 律师事务所周四提起诉讼,辩称 GitHub 和 CapitalOne 在对违规行为的回应中表现出疏忽。该公司代表受违规行为影响的人提起集体诉讼,指控两家公司未能保护客户数据。 在 CapitalOne 使用的 Amazon 云存储服务中的防火墙配置错误被利用后,数千万客户的个人信息暴露出来。该漏洞暴露了约140,000个社会安全号码和80,000个银行账号,以及美国和加拿大数百万的信用卡申请。 据称,西雅图软件工程师 Paige Thompson 涉嫌犯下数据泄露罪,并已经于本周早些时候被捕。Thompson 是亚马逊前雇员,据称于3月份访问了该数据,并在4月份发布了有关她在 GitHub 上窃取信息的消息。另一位 GitHub 用户通知了CapitalOne,后者随后通知了 FBI。 “由于GitHub未能监控,删除或以其他方式识别和处理GitHub及其网站上显示,披露和使用的明显被...
- 下一篇
OSChina 周日乱弹 —— 食食物者为俊杰
Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @无形的肖申克 :分享Zedd/Jon Bellion的单曲《Beautiful Now》: 《Beautiful Now》- Zedd/Jon Bellion 手机党少年们想听歌,请使劲儿戳(这里) @jun-s :8月2号了,终于结束上半年的单身生活很开心,很激动,今天下班都可以早点走了,准备去超市,买的存粮,开开心心准备下半年的单身生活了。 这才结束上半年么? @MissThee:一年16个月 @ jun-s:@MissThee 那四个月是加班加出来的 不知道这样单身的梦还要做多久? @巴拉迪维 :你做过有颜色的梦吗?我的梦,好像都是灰色的 可以给你的梦上色啊, 清朝的黑白照片都能上色, 所以说吧, 你的梦要什么颜色? 乐色…… @clouddyy :约妹子再次失败,点一首《凉凉》送给自己 约妹子还约死了么? @bug007 :家里介绍一妹子,两个月,手也拉了,亲也亲过了,前天表白了下把自己表死了 看来你表白的不对劲儿啊, 至少对象不对劲儿。 感觉你要是个喵的话, 还是可以收货妹子的。 你喜欢的那个妹子也有求而不得的人。 @天...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS6,CentOS7官方镜像安装Oracle11G
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Windows10,CentOS7,CentOS8安装Nodejs环境
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- CentOS8编译安装MySQL8.0.19
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS8安装Docker,最新的服务器搭配容器使用
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- SpringBoot2整合Redis,开启缓存,提高访问速度