Host PHP 与 Docker PHP:慢 5 倍

pla*_*one 4 php linux performance docker

我们使用 docker 进行 PHP 开发,我很好奇在我的主机上运行 PHP 7.4 与在 docker 容器中运行代码时的性能差异。

我正在运行最新Linux Mint版本,而 docker 版本是Docker version 20.10.17- 没有特殊的非标准配置。

为了对两个 PHP 环境进行公平的比较,我仔细检查了配置,当然还禁用了 xdebug。

然后我运行一些基本的 php 基准测试,这是我在 github 上找到的:

<?php

$startTime = time();
$runSeconds = 5;
$rounds = 5;
$count = 0;
for ($i=0; $i<$rounds; $i++) {
    while ((time()-$startTime) <= $runSeconds) {
        serialize(['bar'=>'foo']);
        $count ++;
    }
    $round = $i+1;
    $startTime += $runSeconds;
    $count = number_format($count);
    echo "Round {$round}: {$count} /per {$runSeconds} second\n";
    $count = 0;
}
Run Code Online (Sandbox Code Playgroud)

我的主机 PHP 7.4 上的结果:

Round 1: 93,052,589 /per 5 second
Round 2: 89,096,400 /per 5 second
Round 3: 89,190,317 /per 5 second
Round 4: 89,145,362 /per 5 second
Round 5: 88,923,066 /per 5 second
Run Code Online (Sandbox Code Playgroud)

码头工人 PHP 7.4

https://hub.docker.com/layers/php/library/php/7.4.30-zts-alpine3.15/images/sha256-6e1a13b9e0446eedc3a1220b24ed52727b3330a165b5787395c1a3082e355481?context=explore

Round 1: 18,937,581 /per 5 second
Round 2: 16,089,889 /per 5 second
Round 3: 16,083,545 /per 5 second
Round 4: 16,087,953 /per 5 second
Round 5: 16,079,214 /per 5 second

Run Code Online (Sandbox Code Playgroud)

这是一个巨大的差异。是否有一些常见的瓶颈可以解释这种巨大的差异?

我认为 Docker 没有太大的开销,至少应该可以忽略不计的开销 - 但我认为性能慢 5 倍已经很多了。

Ais*_*tis 6

Alpine我可以使用非常相似的测试来确认在我的机器上执行速度明显变慢。

似乎它可能与不同的底层库和不同的内核选项有关(例如RAM大页面被禁用,opcache不会从中受益)。

比较(越高越好,迭代计数为 25 秒,禁用 opcache):

OS 7.4.18 (current)             Total: 89,226,100
Custom 7.4.32 Alpine            Total: 57,472,042
Official 7.4.33 Bullseye        Total: 101,363,370
Official 8.1.15 Alpine          Total: 53,698,833
Official 8.1.15 Bullseye        Total: 103,377,353
Official 8.1.15 Bullseye+JIT    Total: 102,026,978
Official 7.4.33 Alpine          Total: 58,911,670
Run Code Online (Sandbox Code Playgroud)

测试片段:

...

for ($i = 0; $i < $rounds; $i++) {
    $startTime = time();
    while ((time() - $startTime) <= $runSeconds) {
        $prefix = (string)$count . '|' . (string)$i;
        json_encode([$prefix . 'bar' => $prefix . 'foo'], JSON_THROW_ON_ERROR);
        $count++;
    }

    $round = $i + 1;
    $startTime += $runSeconds;
    $total += $count;
    $count = number_format($count);

    echo " Round {$round}: {$count} per {$runSeconds} second\n";

    $count = 0;
}
echo " Total: " . number_format($total) . "\n";
Run Code Online (Sandbox Code Playgroud)