Docker 图像的性能差异
Performance difference in Docker images
我有一个 .NET Core 2.0 控制台应用程序,它具有不同的性能结果,具体取决于它 运行 所在的 Docker 基础映像。应用程序对 .NET 中的 String.StartsWith(string) 函数执行多次调用。这是 Program.cs 文件:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
namespace ConsoleApp {
class Program {
private static string variable = "MYTEXTSTRING";
private static IEnumerable<string> collection = new[] { "FAF", "LEP", "GHI" };
static void Main(string[] args) {
int counter = args.Length > 0 ? Int32.Parse(args[0]) : 1000;
var stopwatch = new Stopwatch();
stopwatch.Start();
for (int i = 0; i < counter; i++) {
foreach (string str in collection) {
variable.StartsWith(str);
}
}
stopwatch.Stop();
Console.WriteLine($"Elapsed time: '{stopwatch.ElapsedMilliseconds}ms' - {counter * collection.Count()} calls to string.StartsWith()");
Console.ReadLine();
}
}
}
此代码然后在 Linux Ubuntu VM 的 Docker 容器中运行。
根据我使用的基本图像,我看到非常不同的性能结果。
这是使用 Red Hat 基础映像的 Docker 文件:
# Red Hat base image
FROM registry.access.redhat.com/dotnet/dotnet-20-rhel7
# set the working directory
WORKDIR /app
# copy files
ADD . /app
# run Model.Build
CMD ["dotnet", "ConsoleApp.dll", "20000"]
这是使用 Linux Debian 基础映像的 Docker 文件:
# Docker Hub base image
FROM microsoft/dotnet:2.0.5-runtime-jessie
# set the working directory
WORKDIR /app
# copy files
ADD . /app
# run Model.Build
CMD ["dotnet", "ConsoleApp.dll", "20000"]
如您所见,除了基本图像外,这两个 Docker 文件实际上是相同的。
以下是我得到的性能结果:
- Red Hat 基本映像:"Elapsed time: '540ms' - 60000 calls to string.StartsWith()"。
- Docker 集线器基础图像:"Elapsed time: '15ms' - 60000 calls to string.StartsWith()".
- 本机执行:"Elapsed time: '14ms' - 60000 calls to string.StartsWith()"
因此,虽然使用 Debian 基础映像的容器的性能结果与本机执行非常相似,但使用 Red Hat 映像的容器的性能要慢得多。
问题:
为什么 StartWith() 函数的执行方式如此不同?使用 Red Hat 基本映像时,是什么导致性能下降这么多?
谢谢。
StartsWith
考虑到了文化。容器区域性不同,因为它们没有相同的 LANG
环境变量。
您可以使用 StartsWith
重载之一来更改考虑文化的方式(例如 variable.StartsWith(str, StringComparison.Ordinal)
)。
我有一个 .NET Core 2.0 控制台应用程序,它具有不同的性能结果,具体取决于它 运行 所在的 Docker 基础映像。应用程序对 .NET 中的 String.StartsWith(string) 函数执行多次调用。这是 Program.cs 文件:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
namespace ConsoleApp {
class Program {
private static string variable = "MYTEXTSTRING";
private static IEnumerable<string> collection = new[] { "FAF", "LEP", "GHI" };
static void Main(string[] args) {
int counter = args.Length > 0 ? Int32.Parse(args[0]) : 1000;
var stopwatch = new Stopwatch();
stopwatch.Start();
for (int i = 0; i < counter; i++) {
foreach (string str in collection) {
variable.StartsWith(str);
}
}
stopwatch.Stop();
Console.WriteLine($"Elapsed time: '{stopwatch.ElapsedMilliseconds}ms' - {counter * collection.Count()} calls to string.StartsWith()");
Console.ReadLine();
}
}
}
此代码然后在 Linux Ubuntu VM 的 Docker 容器中运行。 根据我使用的基本图像,我看到非常不同的性能结果。
这是使用 Red Hat 基础映像的 Docker 文件:
# Red Hat base image
FROM registry.access.redhat.com/dotnet/dotnet-20-rhel7
# set the working directory
WORKDIR /app
# copy files
ADD . /app
# run Model.Build
CMD ["dotnet", "ConsoleApp.dll", "20000"]
这是使用 Linux Debian 基础映像的 Docker 文件:
# Docker Hub base image
FROM microsoft/dotnet:2.0.5-runtime-jessie
# set the working directory
WORKDIR /app
# copy files
ADD . /app
# run Model.Build
CMD ["dotnet", "ConsoleApp.dll", "20000"]
如您所见,除了基本图像外,这两个 Docker 文件实际上是相同的。 以下是我得到的性能结果:
- Red Hat 基本映像:"Elapsed time: '540ms' - 60000 calls to string.StartsWith()"。
- Docker 集线器基础图像:"Elapsed time: '15ms' - 60000 calls to string.StartsWith()".
- 本机执行:"Elapsed time: '14ms' - 60000 calls to string.StartsWith()"
因此,虽然使用 Debian 基础映像的容器的性能结果与本机执行非常相似,但使用 Red Hat 映像的容器的性能要慢得多。
问题: 为什么 StartWith() 函数的执行方式如此不同?使用 Red Hat 基本映像时,是什么导致性能下降这么多?
谢谢。
StartsWith
考虑到了文化。容器区域性不同,因为它们没有相同的 LANG
环境变量。
您可以使用 StartsWith
重载之一来更改考虑文化的方式(例如 variable.StartsWith(str, StringComparison.Ordinal)
)。