PHP 在 Amazon EC2 的 m5 (Intel) 與 m6g (ARM) 的效能差異

先前在「Amazon EC2 的 M6g 系列正式推出了」這邊提到了 AWSAmazon EC2 上推出了以 ARM 為架構的 m6g 系列機器,剛剛看到有人拿 PHP 上的應用丟出測試的差異了:「Improving performance of PHP for Arm64 and impact on Amazon EC2 M6g instances」。

最先要注意的應該是這張:

在 PHP 7.3 的時候 Intel 平台的 m5 跑比較快,但到了 PHP 7.4 就變成 ARM 的 m6g 跑比較快了,不過這兩個版本的差異都不算太大,而到了還在開發的 PHP 8 則是出現了比較大的差距。

作者有提到主要的原因是在 PHP 7.4 之前 ARM 上不會啟用 Zend optimizer,而這個功能對效能的影響差很多,在 PHP 7.4 打開後就反轉了:

Zend optimizer is a component of the PHP runtime system that improves performance by up to 30% on a range of Zend micro-benchmarks. Before PHP 7.4 the Zend optimizer was not enabled for Arm.

而 PHP 8 的差距拉大,則是因為 PHP 有更多針對 ARM 平台的改善,像是這邊提到的 NEON 指令集:

PHP-8 plans to release in 2021 with more improvements for Arm64: an improved toupper/tolower function brings performance up by 16.5x. https://github.com/php/php-src/pull/4439

除此之外,AWS 也對 PCRE2 提供了使用 NEON 指令集的加速的 patch:

AWS has contributed changes to PCRE2 release 10.34. PCRE2 version 10.34 is used in PHP-8 to match regular expressions. PCRE2 accounted for about 8% of execution time in WordPress benchmark. The change contributed by AWS to PCRE2 vectorizes first character match and matching pairs of characters with NEON instructions: performance improves by up to 8x on M6g.

這樣可以看到 ARM 平常應該會愈來愈成熟,而更重要的是 m6g 系列機器比 m5 便宜不少:以作者測試的 {m5,m6g}.4xlarge 來看,分別是 USD$0.768/hr 與 USD$0.616/hr,大約是 20% 的差距,加上效能上的差距,C/P 值看起來是真的有到官方宣稱的 40%,這點在其他 Plurk 也測出了類似的結果

未來除非是 binary-only 的東西,不然應該會朝著往 ARM 上面測過,再決定要怎麼選 instance type...

原來 ZendFramework 1 還有在出新版...

在「Zend Framework 1.12.18 Released!」這邊看到因為「ZF2016-11: Potential Insufficient Entropy Vulnerability in ZF1」而推出新版的消息...

另外在「Changelog 1.12.18」這頁可以看到還是有一些 bugfix,所以其實都還是有在維護?(記憶中以為現在沒在管了...)

Zend Framework 1 的 Zend_View 與 Zend Framework 2 的 Zend\View 的差異...

Zend Framework 1 的 Zend_View 實踐了 Rasmus Lerdorf (PHP 發明人) 的想法「PHP 本身就是 template language,不應該在 PHP 裡面再發明一套 template language」。

Zend_View 是可以獨立拿出來用的,使用方式很簡單:

$view = new Zend_View();
$view->setBasePath(realpath(__DIR__ . '/../application/view'));
echo $view->render('index/index.phtml');

這樣對應的 template 檔案是 application/view/scripts/index/index.phtml

Zend Framework 2 除了改用 namespace 外 (所以名稱從原來的 "_" 改成 "\"),還把 Zend\View 深度整合到 Zend\Mvc 裡,這使得要獨立拿出來用的手續就變得... 超... 麻... 煩...

透過 Composer 安裝的人除了在 composer.json 裡面要設定 zendframework/zend-view 外,還要設定 zendframework/zend-filter 才會動 (不知道為什麼沒被放進 dependency),像是這樣:

    "require": {
        "zendframework/zend-filter": "2.2.*",
        "zendframework/zend-view": "2.2.*"
    }

另外 ZF 2 的 Zend\View 則是透過 resolver 物件設定要讀哪個目錄,而非之前用 setBasePath 打發:

$resolver = new \Zend\View\Resolver\TemplatePathStack(
    array(
        'script_paths' => array(
            realpath(__DIR__ . '/../webdata/view/')
        )
    )
);

$renderer = new \Zend\View\Renderer\PhpRenderer();
$renderer->setResolver($resolver);

echo $renderer->render('index/index.phtml');

這樣對應的 template 檔案是 webdata/view/index/index.phtml,跟 ZF1 相比少了一個 scripts

ZF 的文件一如往常的難讀,還是要去翻 source code 才知道要這樣用,所以也跟往常一樣,寫下來避免之後又忘記...