C#은 관리형 언어(Managed Language)이다. 개발자가 메모리 할당과 해제를 하는 것을 CLR(런타임 환경)이 이를 대신해 주고 가비지 컬렉션(Garbage Collection)으로 사용하지 않는 메모리를 시스템이 자동으로 회수하여 메모리 누수를 방지한다.
대신에 빌드하면 소스코드가 바로 기계어로 바뀌는 것이 아니라 중간 언어(IL, Intermediate Language)로 컴파일된 실행 시점에 JIT(Just-In-Time)에 의해 기계어로 번역된다. 그래서 파일(exe, dll)을 ILSpy 같은 툴로 보면 소스코드가 훤히 보여 중요한 문자열을 숨기지 못하는 단점이 있다.
C#의 AOT(Ahead-of-Time) 컴파일은 애플리케이션을 실행하기 전(빌드 시점)에 코드를 해당 운영체제와 CPU가 이해할 수 있는 네이티브 기계어로 미리 번역해 두는 기술이다. 이것 때문에 이를 활용하면 ILSpy툴로 내용(소스)을 볼 수 없다. 다만 문자열은 헥사에니터 같은것으로 충분히 볼 수 있기 때문에 이를 보완해야 한다.
C++ constexpr, zig comptime, rust의 매크로함수인 obfstr!함수를 이용하여 컴파일 타임에 문자열을 난독화한다. 다만 여기에서는 AOT만을 이용하여 기본을 학습한 후 이것을 토대로 zig, rust, c++를 라이브러리로 만들어 c#에서 활용해 보려고 한다.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>disable</ImplicitUsings>
<Nullable>enable</Nullable>
<PublishAot>true</PublishAot>
<IsAotCompatible>true</IsAotCompatible>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
</Project>
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);
}
위의 동기 클로저와 비교한 아래의 예제는 비동기, 비동기 클로저에 대한 보기다.