Do you know that your code in the docker container can work as fast as on the host machine? In some cases, it can be even faster!
Today, we’ll share some tips on optimizing the Docker settings that allowed us to decrease processing time by 15%.
Before we begin, let’s go through the main environment features and tools that we’ll be using in our tests:
We’ll run CPU and I/O tests on the host machine and inside the container.
One of the benefits of containers over virtual machines is that you isolate processes without any performance losses or hypervisor corruption. However, Docker can slow down your code and skew efficiency indicators. And even if containers don’t slow down your code, there is a chance that it can run even faster with some optimization.
How is the difference in performance possible?
There is a theory that Docker's security features slow down computing. This is because Docker adds extra layers of security to prevent programs from escaping the container onto the host. One such security mechanism is seccomp. It defines what the system calls can run containers. It is important to note that this mechanism shouldn’t make such a difference, and there are suggestions on how to level the difference, but the corrections have not been applied yet.
To check if speedups are possible in your calculations quickly, you can run the container in privileged mode. It turns off the safety features, so you can determine if the slowdown is because of them. For this, run the container using the key —privileged:
Use the following parameter for docker-compose:
It is important to highlight that running containers in privileged mode can be unsafe. Click to read why and how to deal with it.
The first test we will run is computational operations testing in different container launch modes. As a basic benchmark, we will use the following computational operations:
We will do each test five times and use the average value as an estimated result.
Let's do the first three tests:
Here are the results we’ve got:
As you can see, inside the container, calculations are 13% longer but 4% faster than on the host machine when using the privileged mode. Parameter optimization showed the expected values. Moreover, in a container, calculations are even faster.
Next, we will test various images. It may not be clear right away, but different images use different versions of services that can affect calculation performance. Let's run three tests using the following Python images:
Here are the results we’ve got:
As you can see, calculations in the slim image are 2% faster than the official image and 20% faster than the alpine. Please note that this benchmark is faster than host machines on 25+% in all tests.
Also, we want to stress one more time that these tests are focused on calculations. In containers running in production, such operations are mixed with others, and there will not be such a big difference. You can learn more about the choice of image and the difference between them on Medium.
Now, let’s compare the calculations of different versions of Python distributions. We'll run three tests and see what results we get. Here are the versions of Python we’ll use:
And here is a diagram with the results:
We’ve got quite unexpected results. The test performed on the python:3.10-slim image is 70% faster than the test on the host machine. This shows us another option for speeding up your applications in a container.
In addition to computational tests, it is of interest to run input/output tests on the host machine and in the container. It is expected that these tests will show differences in the results.
As a benchmark, we will use the script, which is a character-by-character read and write of a 128MB file.
Let's run four tests:
And here are the results we’ve got:
As you can see, the computations in the container are 40% slower. You can get similar results using an image based on Ubuntu 20.04 with privileged mode only. Note that in the tests mentioned before, this image proved to be worse than others.
Now, we hope you have a better understanding of why it is necessary to run tests and find your best configuration for each task.
These are not all possible tests and reasons for poor performance. You can investigate network overhead issues more by yourself, as containers can double the latency. We will not consider other tests in detail because they often show a small difference.
Also, the use of volumes can add extra overhead. This is especially important for Windows and macOS users. On Linux, they incur no overhead since the underlying VFS is shared between the host and container directly. But you don't need to refuse to use volumes. You should understand that many images are designed to use them (for example, some images for the database).
Our today's results show that containers provide equal or better performance in almost all cases. And here are the main insights we wanted to share:
Finally, we want to note that the tuning of the applications that use GPU servers is another big topic. So if you want us to get it covered, let us know.
Read more on Docker speed optimization:
→ Six Ways to Build Docker Images Faster
→ Speed Up Your Development Flow With These Dockerfile Best Practices
→ An Updated Performance Comparison of Virtual Machines and Linux Containers