DEV Community

Cover image for From C# to Rust: Porting MathFlow to Create MathCore - A Symbolic Math Library Journey
Berkant
Berkant

Posted on

From C# to Rust: Porting MathFlow to Create MathCore - A Symbolic Math Library Journey

# From C# to Rust: Building a Symbolic Math Library πŸš€

Hey DEV community! Today I want to share my journey of porting a symbolic math library from C# to Rust, and what I learned along the way.

## πŸ“– The Story

Last year, I built MathFlow - a symbolic math library for C#. It worked great, but I was curious about Rust's performance claims. So I decided to rebuild it as
MathCore in Rust.

The results? Mind-blowing! 🀯

## 🎯 Quick Comparison









πŸ”· C# (MathFlow) πŸ¦€ Rust (MathCore)

 var expr = MathExpression .Parse("x^2 + 2*x + 1"); var derivative = expr .Differentiate("x"); var result = expr .Evaluate(new { x = 5 }); let expr = MathCore::parse( "x^2 + 2*x + 1" )?; let derivative = MathCore::differentiate( &expr, "x" )?; let result = math.calculate( &expr, &[("x", 5.0)] )?; 

⚑ Performance Results

I was shocked by these numbers:

| Operation | C# (MathFlow) | Rust (MathCore) | Difference |
|------------------|---------------|-----------------|----------------|
| Parse Expression | 245 ¡s | 89 ¡s | 2.7x faster ✨ |
| Differentiate | 1,230 ¡s | 456 ¡s | 2.7x faster ✨ |
| Solve Equation | 890 Β΅s | 234 Β΅s | 3.8x faster πŸš€ |
| Memory Usage | 847 MB | 124 MB | 6.8x less 🎯 |


πŸ’‘ Key Differences I Discovered

1️⃣ Error Handling

 C# Way (Exceptions): try { var result = MathExpression.Parse("invalid"); } catch (ParseException e) { Console.WriteLine($"Oops: {e.Message}"); } Rust Way (Result Type): match MathCore::parse("invalid") { Ok(expr) => println!("Success!"), Err(e) => println!("Oops: {}", e), } 

πŸ’­ Insight: Rust forces you to handle errors. No more surprise crashes in production!


2️⃣ Memory Management

C#:

  • βœ… Garbage collector handles everything
  • ❌ Random GC pauses
  • ❌ Unpredictable performance

Rust:

  • βœ… Predictable performance
  • βœ… No GC pauses
  • ❌ Must think about ownership

3️⃣ Real-World Example

Let's solve a physics problem - projectile motion with air resistance:

 // Calculate trajectory var equation = @" y = v0*sin(ΞΈ)*t - 0.5*g*t^2 "; var solver = new MathEngine(); var trajectory = solver .Parse(equation) .Substitute(new { v0 = 100, ΞΈ = Math.PI/4, g = 9.81 }); // Calculate trajectory let equation = "  y = v0*sin(ΞΈ)*t - 0.5*g*t^2 ";  let math = MathCore::new(); let trajectory = math .calculate(equation, &[ ("v0", 100.0), ("ΞΈ", PI/4.0), ("g", 9.81), ])?; 

🎨 Architecture Evolution

From OOP to Functional

 C# (Object-Oriented): public abstract class Expression { public abstract double Evaluate(); } public class AddExpr : Expression { private Expression left, right; public override double Evaluate() { return left.Evaluate() + right.Evaluate(); } } 
 Rust (Algebraic Data Types): enum Expr { Number(f64), Add(Box<Expr>, Box<Expr>), } fn evaluate(expr: &Expr) -> f64 { match expr { Expr::Number(n) => *n, Expr::Add(l, r) => evaluate(l) + evaluate(r), } } 

🎯 Why this matters: Pattern matching eliminated entire class hierarchies!


πŸš€ Cool Features in Both

Features Comparison

| Feature | MathFlow (C#) | MathCore (Rust) |
|--------------------------|---------------|-----------------|
| Symbolic Differentiation | βœ… | βœ… |
| Equation Solving | βœ… | βœ… |
| Matrix Operations | βœ… | βœ… |
| Complex Numbers | βœ… | βœ… |
| Arbitrary Precision | βœ… | βœ… |
| Parallel Computation | βœ… Tasks | βœ… Rayon |
| WASM Support | ⏳ Coming | βœ… Ready |
| FFT | βœ… | βœ… |


πŸ“¦ Try Them Out!

For .NET Developers:

dotnet add package MathFlow

 using MathFlow; var math = new MathEngine(); var derivative = math.Differentiate("sin(x^2)", "x"); Console.WriteLine(derivative); // Output: 2*x*cos(x^2) 

For Rust Developers:

cargo add mathcore

 use mathcore::MathCore; fn main() { let derivative = MathCore::differentiate("sin(x^2)", "x").unwrap(); println!("{}", derivative); // Output: 2*x*cos(x^2) } 

πŸ€” Which Should You Use?

Choose MathFlow (C#) if you:

  • πŸ”· Are building .NET applications
  • πŸ”· Use Unity for game development
  • πŸ”· Want fastest development time
  • πŸ”· Prefer familiar OOP patterns

Choose MathCore (Rust) if you:

  • πŸ¦€ Need maximum performance
  • πŸ¦€ Want to compile to WASM
  • πŸ¦€ Build system-level tools
  • πŸ¦€ Care about memory efficiency

πŸ“ˆ What I Learned

  1. Rust's ownership model prevents entire categories of bugs
  2. Pattern matching can replace complex OOP hierarchies
  3. Zero-cost abstractions are real - high-level Rust code is FAST
  4. Both languages have their sweet spots

πŸ”— Links & Resources

MathFlow (C#)

https://github.com/Nonanti/MathFlow
https://nuget.org/packages/MathFlow

MathCore (Rust)

https://github.com/Nonanti/mathcore
https://crates.io/crates/mathcore
https://docs.rs/mathcore


πŸ’¬ Let's Discuss!

Have you ported a project between languages? What was your experience?

Drop a comment below! πŸ‘‡


If you found this helpful, consider giving the repos a ⭐!

Happy coding! πŸš€

Top comments (0)