所有文章 > API开发 > 在 .NET 和 Python 中创建了相同的 API — 哪个性能更好
在 .NET 和 Python 中创建了相同的 API — 哪个性能更好

在 .NET 和 Python 中创建了相同的 API — 哪个性能更好

我将比较一种编程语言与另一种编程语言的性能结果。我从简单的操作开始,但后来转向更复杂的操作。

用例

我创建了一个 GET 方法,用于计算数字 n 的阶乘。例如,5!(读作 “five factorial”) 的计算方式如下

5! = 5 × 4 × 3 × 2 × 1 = 120

我知道这是一个基本的比较,但更广泛的比较正在进行中。

摘要步骤

我们可以使用流行的框架(ASP.NET Core for C# 和 FastAPI for Python)在这两种语言中创建基本的 REST API,并通过创建相同的 API 来比较两种语言的性能。

API 实现

  • 使用 ASP.NET Core 在 C# 中编写 API。
  • 使用 FastAPI 在 Python 中编写 API。

性能比较

对 API 使用基准测试工具进行ApacheBench

  • 基本负载测试
  • 延迟测试
  • 故障率测试
  • 长连接测试
  • 压力测试

测量吞吐量、延迟和请求处理时间。

开始

让我们首先创建一个 .Net API 项目,按照以下步骤操作。

使用 .Net SDK 创建项目

运行以下命令以创建新项目。

dotnet new webapi -n ApiPerformanceTest  
cd ApiPerformanceTest

最小 GET API

使用带有路由的最小 API 创建简单的 GET 方法/factorial

app.MapGet("/factorial", (int n) =>  
{
long Factorial(int number)
{
return number <= 1 ? 1 : number * Factorial(number - 1);
}

long result = Factorial(n);
return result;
})
.WithName("GetFactorial")
.WithOpenApi();

并使用以下命令运行 API

dotnet run

API 将可以访问,其中检查 for defined in 和 是我们将为其计算阶乘的数字。http://localhost:{portNo}/Factorial/{n}portNo lauchSettings.jsonn

其次,让我们在 Python 中创建一个类似的 GET 方法

使用以下命令安装 FastAPI 和 Uvicorn

pip install fastapi uvicorn

创建包含以下内容的文件。main.py

from fastapi import FastAPI  

app = FastAPI()

def factorial(n: int) -> int:
return 1 if n <= 1 else n * factorial(n - 1)

@app.get("/factorial/{n}")
def get_factorial(n: int):
result = factorial(n)
return {"factorial": result}

用于运行 FastAPI 服务器。uvicorn

uvicorn main:app --reload

API 将在 where is 我们将为其计算阶乘的数字进行访问。http://127.0.0.1:8000/factorial/{n}n

性能比较

ApacheBench (ab) 通常用于 Web 服务器、API 和应用程序的性能基准测试。

安装

sudo apt-get install apache2-utils

用法

确保两个应用程序服务器都可以在定义的端口号处访问,并且应该已经启动并运行,没有任何错误。

ab -n 1000 -c 10 http://localhost:5030/factorial?n=10  
ab -n 1000 -c 10 http://127.0.0.1:8000/factorial/10

.Net 结果

通过在本地调用在 5030 上运行的 .Net API 从 Apache Bench 返回的性能结果。

cmd > ab -n 1000 -c 10 http://localhost:5030/factorial?n=10
This is ApacheBench, Version 2.3 <$Revision: 1903618 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests


Server Software: Kestrel
Server Hostname: localhost
Server Port: 5030

Document Path: /factorial?n=10
Document Length: 7 bytes

Concurrency Level: 10
Time taken for tests: 0.184 seconds
Complete requests: 1000
Failed requests: 0
Total transferred: 146000 bytes
HTML transferred: 7000 bytes
Requests per second: 5439.01 [#/sec] (mean)
Time per request: 1.839 [ms] (mean)
Time per request: 0.184 [ms] (mean, across all concurrent requests)
Transfer rate: 775.48 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.3 0 5
Processing: 0 2 0.9 2 9
Waiting: 0 1 0.9 1 8
Total: 0 2 0.9 2 9

Percentage of the requests served within a certain time (ms)
50% 2
66% 2
75% 2
80% 2
90% 2
95% 3
98% 5
99% 6
100% 9 (longest request)

Python 结果

通过在本地调用在 8000 上运行的 Python API 从 Apache Bench 返回的性能结果。

cmd > ab -n 1000 -c 10 http://127.0.0.1:8000/factorial/10
This is ApacheBench, Version 2.3 <$Revision: 1903618 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests


Server Software: uvicorn
Server Hostname: 127.0.0.1
Server Port: 8000

Document Path: /factorial/10
Document Length: 21 bytes

Concurrency Level: 10
Time taken for tests: 0.766 seconds
Complete requests: 1000
Failed requests: 0
Total transferred: 165000 bytes
HTML transferred: 21000 bytes
Requests per second: 1305.69 [#/sec] (mean)
Time per request: 7.659 [ms] (mean)
Time per request: 0.766 [ms] (mean, across all concurrent requests)
Transfer rate: 210.39 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.3 0 2
Processing: 3 7 3.6 7 41
Waiting: 2 6 3.5 6 41
Total: 3 8 3.6 7 41

Percentage of the requests served within a certain time (ms)
50% 7
66% 8
75% 8
80% 8
90% 9
95% 9
98% 11
99% 38
100% 41 (longest request)

比较

C#(带有 Kestrel 的 .NET Core)

  • 每秒请求数:5439.01 [#/秒]
  • **每个请求的时间(平均值):**1.839 毫秒
  • 传输速率:775.48 KB/秒
  • **连接时间(平均值):**2 ms
  • 最长请求时间:9 毫秒

Python(FastAPI 与 Uvicorn)

  • 每秒请求数:1305.69 [#/秒]
  • **每个请求的时间(平均值):**7.659 毫秒
  • 传输速率:210.39 KB/秒
  • **连接时间(平均值):**8 ms
  • 最长请求时间:41 毫秒

主要观察

每秒请求数

  • C#:每秒 5439 个请求。
  • Python:每秒 1305 个请求。
  • C# 在每秒处理请求方面的性能大约高出 4 倍。

每个请求的时间

  • C#:每个请求 1.839 毫秒。
  • Python:每个请求 7.659 毫秒。
  • 与 Python 相比,C# 每个请求的响应速度提高了 4 倍以上。

传输速率

  • C#:775.48 KB/秒
  • Python:210.39 KB/秒
  • C# 的传输速率要高得多,这意味着它可以处理更多的数据吞吐量。

连接时间

  • C#:中位连接时间为 2 毫秒,最长请求为 9 毫秒。
  • Python:中位连接时间为 7 毫秒,最长请求时间为 41 毫秒。
  • C# 在处理单个请求连接时效率更高。

一致性

  • C# 以最小的偏差显示更一致的性能,而 Python 则显示一些峰值,尤其是在最长的请求时间 (41 毫秒) 中。

简单负载测试

在高负载下测量吞吐量和响应时间,同时提高并发性。

// For .Net  
ab -n 10000 -c 100 http://127.0.0.1:5219/factorial?n=10

// For Python
ab -n 10000 -c 100 http://127.0.0.1:8000/factorial?n=10

下表比较了 .NET (Kestrel) 和 Python (Uvicorn) 之间的基准测试结果

延迟测试

评估单个请求的响应时间以评估延迟。

// For .Net  
ab -n 1000 -c 1 http://127.0.0.1:5219/factorial?n=10

// For Python
ab -n 1000 -c 1 http://127.0.0.1:8000/factorial?n=10

下表比较了 .NET (Kestrel) 和 Python (Uvicorn) 之间的基准测试结果

故障率测试

检查在中等负载下有多少个请求失败。

// For .Net  
ab -n 10000 -c 10 http://127.0.0.1:5219/factorial?n=10

// For Python
ab -n 10000 -c 10 http://127.0.0.1:8000/factorial?n=10

下表比较了 .NET (Kestrel) 和 Python (Uvicorn) 之间的延迟测试结果,对 10000 个请求使用并发级别 10

长连接测试

使用持久连接时测量性能。

// For .Net  
ab -n 10000 -c 10 -H "Connection: Keep-Alive" http://127.0.0.1:5219/factorial?n=10

// For Python
ab -n 10000 -c 10 -H "Connection: Keep-Alive" http://127.0.0.1:8000/factorial?n=10

以下是 Kestrel 和 Uvicorn 服务器在用于 10000 个并发级别为 10 的请求时的比较Keep-Alive

压力测试

评估极端条件下的服务器限制和行为。

// For .Net  
ab -n 50000 -c 200 http://127.0.0.1:5219/factorial?n=10

// For Python
ab -n 50000 -c 200 http://127.0.0.1:8000/factorial?n=10

这是 Kestrel (.NET) 和 Uvicorn (FastAPI) 之间的性能比较,它们的负载要高得多,为 50,000 个请求和 200 个并发连接

在本次基准测试中**,带有 Kestrel 的 C#** 的性能明显优于带有 FastAPI 和 Uvicorn 的 Python

  • 每秒请求数更高。
  • 缩短每个请求的时间。
  • 更好的数据传输速率。
  • 更一致的连接时间。

对于高性能应用程序,尤其是在处理大量并发请求时,C# 在此方案中提供更好的性能。

文章转自微信公众号@DotNet NB

#你可能也喜欢这些API文章!