在 .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
最新文章
- 小红书AI文章风格转换:违禁词替换与内容优化技巧指南
- REST API 设计:过滤、排序和分页
- 认证与授权API对比:OAuth vs JWT
- 如何获取 Coze开放平台 API 密钥(分步指南)
- 首次构建 API 时的 10 个错误状态代码以及如何修复它们
- 当中医遇上AI:贝业斯如何革新中医诊断
- 如何使用OAuth作用域为您的API添加细粒度权限
- LLM API:2025年的应用场景、工具与最佳实践 – Orq.ai
- API密钥——什么是API Key 密钥?
- 华为 UCM 推理技术加持:2025 工业设备秒级监控高并发 API 零门槛实战
- 使用JSON注入攻击API
- 思维链提示工程实战:如何通过API构建复杂推理的AI提示词系统