Rust는 dotnet(C#)에 비해 성능이 우수하다고 알려져 있다.1 대표적인 Rust의 Web Frameworks에는 대표적으로 Actix Web
, Rocket
, Warp
, Axum
, Poem
등이 있는데 각각의 특징을 간략하게 예제(Axum)와 더불어 정리하였다.
프레임워크 | 언어 | 요청/초 | 지연시간(ms) | CPU 사용률 |
---|---|---|---|---|
Actix-web (Rust) | Rust | 748,051 | 1.7 | 98% |
Axum (Rust) | Rust | 723,892 | 1.8 | 97% |
ASP.NET Core | C# | 692,345 | 2.1 | 95% |
Spring Boot | Java | 153,846 | 6.5 | 92% |
Express.js | Node.js | 58,824 | 17.0 | 85% |
dotNET의 경우 Rust에 비해 떨어지지 않는 성능을 보여준다.
Rust는 1.85 버전 기점으로 2024 Edition 발표되었다. Rust Edition이 필요한 이유는 언어 안정성 유지, 프로젝트 간 호환성, 새로운 기능의 점진적인 도입, 개발 과정의 명확성 때문이다. Rust Edition은 2015(1.31.0 전), 2018(1.31.0), 2021(1.56.0), 2024(1.85.0)와 같이 출시 연도와 비슷하게 명명한다.
2024 Edition의 주요 특징은 공식문서에서 확인하고 여기에서는 주요 특징인 Async Closures
에 대하여 간단한 예제와 더불어 C# 언어와 비교해 보았다.
[package]
name = "hello"
version = "0.1.0"
edition = "2024"
[dependencies]
tokio = { version = "1.47.1", features = ["time", "rt", "rt-multi-thread", "macros"] }
// 동기 클로저
fn main() {
let add = |x, y| x + y;
let result = add(1, 2);
println!("{}", result);
}
위의 동기 클로저와 비교한 아래의 예제는 비동기, 비동기 클로저에 대한 보기다.
C# .NET은 Managed Code이다. .NET의 구성요소인 CLR(Common Language Runtime)에서 실행되는 코드 유형이다. 상대적으로 Unmanaged Code는 CLR의 개입 없이 운영체제나 하드웨어에서 직접 실행되는 코드 유형이다. C#보다 머신 수준에 더 가까운 C, C++ 와 같은 언어로 작성된다.1 Managed Code인 C#은 런타임 환경에서 자동으로 메모리 관리(GC, Garbage Collection)를 관리한다.
IDisposable을 구현하는 개체를 사용할 때 using StreamReader
와 같이 사용하면 함수의 블록이 끝날 때 자동으로 메모리에서 개체를 메모리에서 해제한다.2 간혹 개발자 중에 직접 메모리를 해제하고자 할 때 아래와 같이 코드를 작성하곤 하는 데 이러한 방법은 GC를 오해한 까닭에서 나온 결과이다.3
public static void ClearMemory<T>(this List<T> list)
{
int id = GC.GetGeneration(list);
list.Clear();
GC.Collect(id, GCCollectionMode.Forced);
}
GC.Collect()
를 호출하면 가비지 컬렉션이 실행될 가능성을 높이지만 Unmanaged 언어와 같이 바로 메모리가 반환되는 것을 보장하지 않는다. 즉, 힌트를 준 정도의 역할만 할 뿐이고 특히 GC를 자주 호출하면 CPU 시간을 소모하는 작업이기 때문에 오히려 성능에 악영향을 미칠 수 있다.
아래의 예제는 권장하는 코드와 함께 공부 차원에서 직접 작성한 몇 가지 클래스이다.