Serializing and Deserializing .NET Core vs Go Data

Hi% username%







My task was to compare serialization performance for .NET Core and Golang. After searching the Internet, I came across a repository . A simple example of a REST microservice is considered. This is exactly what I need, I thought. After seeing the test results, I was surprised. After looking at the source code, I realized what was wrong. Here's what I didn't like:









It was these shortcomings that led to a more detailed consideration of performance in the framework of the example described above. I hope you find it interesting to know the results.







Composition and description of software



The source code from the repository above was also taken as a basis. What has been finalized:









Modified code is available in the repository .







For clarity, an example JSON response from the server API:







[ { "Id":"id_8299119732867115081", "Name":"name_5541535679032008745", "Time":1566731141 }, ... { "Id":"id_2804604318195309547", "Name":"name_5914011395631118540", "Time":1566731142 } ]
      
      





Customers



To evaluate the performance in each service, three methods are implemented:









Based on these tests, you can evaluate the relative performance of web servers (kestrel and net / http), the performance drop when processing data using and without reflection for implementations in both languages.







Description of testing methodology



Testing was carried out in several stages in order to evaluate the performance of each language and each implementation.

To create a load, the bombardier utility was selected. The utility was launched with the following parameters: -c 125 โ€“d 120s, which can be interpreted as follows: how to use 125 threads with a test time of 120 seconds.







Performance measurement was carried out in 3 stages:







  1. RPS API server dimension. The measurements were carried out in order to be able to assess the impact of processing methods on the performance of each method.
  2. RPS measurement of response processing using reflection.
  3. Measure RPS response processing without using reflection.


Based on these measurements, data were obtained on the performance of response processing. Utilization of all processor cores was 99.8-100%. For the assessment, the initial data of 10, 30, 100, and 500 records were selected. Arrays of 500 records in size are not common in production, but I was interested to see how each of the languages โ€‹โ€‹behaves.







Test stand



All tests were run on a virtual machine running Ubuntu Server 18.04 with all updates for August 2019. It has the following characteristics:









For performance comparison, .NET Core 2.2 and Golang 1.12 were installed.







Well, now it's time to move on to the most interesting - the results.







results



Below is a table with the test results.







alt text







You can immediately notice that Golang has a more productive web server. The difference is about 12% compared to Kestrel in .NET Core.

Based on the data above, 2 graphs were constructed. Next, you can clearly see the comparison of RPS.







alt text







Due to the faster net / http library, Golang shows good results for small data. With an increase in data volume, performance is compared with kestrel.







When using reflection on a small data size, the RPS is approximately the same, taking into account the measurement error. With increasing data size, .NET Core shows more RPS.







When testing without the use of reflection, both languages โ€‹โ€‹showed a performance gain. Golang shows better performance because it has initially higher RPS (requests per second) on tests without processing. On small data, the advantage is significant. With the increase in data size, RPS is almost compared. On the biggest test of 500 records, Golang is again ahead.







alt text







In tests using reflection, Golang lost on all fronts. The performance drop in the worst-case scenarios was over 60%. Implementing serialization out of the box for performance is generally worthless.

Without reflection, Golang was faster in all tests. And with data growth, the advantage of Golang is only growing. In any case, the refusal to use reflection gives a significant performance increase for both Golang and .NETCore, which, in general, should be expected.







findings



What conclusions can be drawn from this small performance comparison? I would like to formulate this in the form of pros and cons for each of the solutions. Let's start with Golang:









.NET Core also has several advantages:









The result can be summarized as follows: if you have a REST API and you are planning a large load, not too complicated business logic, it is better to use Golang, in other cases you can get by with .NET Core. Should I rewrite ready-made solutions from .NET Core to Golang? Everyone will decide for himself.







I hope you find this material useful. All good








All Articles