Turn Your Vehicle Into a Smart Earning Asset

While you’re not driving your car or bike, it can still be working for you. MOTOSHARE helps you earn passive income by connecting your vehicle with trusted renters in your city.

🚗 You set the rental price
🔐 Secure bookings with verified renters
📍 Track your vehicle with GPS integration
💰 Start earning within 48 hours

Join as a Partner Today

It’s simple, safe, and rewarding. Your vehicle. Your rules. Your earnings.

DOTNET: Memory Optimization in .NET with Span

This is a perfect demo topic. Here’s a single, self-contained console app that lets you feel the difference between:

  • 🚫 Without Span<T> – using Substring (allocates new strings every time)
  • With Span<T> – using AsSpan + Slice (no extra allocations)

You’ll get timing + GC stats for both in the same run.


1️⃣ Full Code – Program.cs

Copy–paste this as Program.cs (or replace the existing one in a new console app):



2️⃣ (Optional) Minimal .csproj

If you want a fully explicit project file, create SpanDemo.csproj:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

</Project>
Code language: HTML, XML (xml)

You can change net8.0 to net9.0 or net10.0 depending on your installed SDK.


3️⃣ Step-by-Step: How to Run It

Step 1 – Create a new console app

dotnet new console -n SpanDemo
cd SpanDemo
Code language: JavaScript (javascript)

Step 2 – Replace Program.cs

  • Open Program.cs
  • Delete everything
  • Paste the full code from section 1️⃣

(Optionally replace the generated .csproj with the one in 2️⃣.)

Step 3 – Build and run in Release

dotnet run -c Release

You’ll see output similar to:

=========================================
      Span<T> Demo – Substring vs Span    
=========================================

Items to process: 500,000

Preparing test data...
Warming up (small runs)...
--- Warmup – Substring (no Span) ---
Items processed : 50,000
Time Elapsed    : 45 ms
GC Gen0         : 5
GC Gen1         : 0
GC Gen2         : 0
Managed Memory Δ: 2.30 MB
Checksum (ignore, just prevents JIT from optimizing away work): 1234567

--- Warmup – Span<T> ---
Items processed : 50,000
Time Elapsed    : 20 ms
GC Gen0         : 1
GC Gen1         : 0
GC Gen2         : 0
Managed Memory Δ: 0.20 MB
Checksum (ignore, just prevents JIT from optimizing away work): 1234567

=========== REAL TESTS (Release) ==========

--- WITHOUT Span<T> – using Substring (allocations) ---
Items processed : 500,000
Time Elapsed    : 400 ms
GC Gen0         : 40
GC Gen1         : 2
GC Gen2         : 0
Managed Memory Δ: 20.50 MB
Checksum (ignore, just prevents JIT from optimizing away work): 1234567

--- WITH Span<T> – using AsSpan + Slice (no extra allocations) ---
Items processed : 500,000
Time Elapsed    : 180 ms
GC Gen0         : 4
GC Gen1         : 0
GC Gen2         : 0
Managed Memory Δ: 1.10 MB
Checksum (ignore, just prevents JIT from optimizing away work): 1234567
Code language: HTML, XML (xml)

(Your exact numbers will vary by machine, but the pattern should be similar.)


4️⃣ How to “Experience” and Interpret the Results

Look at these metrics for each scenario:

  • Time Elapsed
  • 🗑 GC Gen0 / Gen1 / Gen2
  • 💾 Managed Memory Δ (MB)

🔴 Scenario 1 – WITHOUT Span<T> (using Substring)

What happens:

  • For each of the 500,000 strings, we call Substringthree times:
    • Each Substring creates a new string allocation on the heap.
    • So we allocate 1.5M strings in the loop.

You’ll typically see:

  • Higher elapsed time
  • Many more Gen0 collections
  • Possibly some Gen1/Gen2 collections
  • Larger Managed Memory Δ

This simulates a typical string parsing / text processing pattern that is allocation-heavy.


🟢 Scenario 2 – WITH Span<T>

What happens:

  • We still have the same 500,000 original strings (same cost as before).
  • But inside the loop we use: ReadOnlySpan<char> span = s.AsSpan(); var part1 = span.Slice(0, 8); var part2 = span.Slice(9, 3); var part3 = span.Slice(span.Length - 10);
  • These are just views (windows) over the same underlying string:
    • No new string objects are created.
    • No extra heap allocations per slice.

You should see:

  • Lower elapsed time (less allocation + less GC work)
  • Much fewer Gen0 collections
  • Gen1/Gen2 often drop to zero
  • Managed Memory Δ is much smaller

This is exactly the benefit of Span<T>:
🔹 Operate on slices of data without additional allocations.


5️⃣ Playing with the Load

To make the impact more dramatic (for demo):

  • Increase item count: const int itemCount = 1_000_000;
  • Or add more slicing and comparisons per string.

Just be aware that very large values can make the Substring scenario quite heavy.


6️⃣ How to Explain This in Training

You can summarize it like this:

  • Without Span<T>, every Substring call allocates a new string. In a tight loop, this leads to tons of small GC’ed objects, more GC cycles, and higher latency.
  • With Span<T>, we use AsSpan + Slice to work with slices of the existing string. No new allocations → lower GC pressurebetter throughput.

Subscribe
Notify of
guest
0 Comments
Newest
Oldest Most Voted
Inline Feedbacks
View all comments

Certification Courses

DevOpsSchool has introduced a series of professional certification courses designed to enhance your skills and expertise in cutting-edge technologies and methodologies. Whether you are aiming to excel in development, security, or operations, these certifications provide a comprehensive learning experience. Explore the following programs:

DevOps Certification, SRE Certification, and DevSecOps Certification by DevOpsSchool

Explore our DevOps Certification, SRE Certification, and DevSecOps Certification programs at DevOpsSchool. Gain the expertise needed to excel in your career with hands-on training and globally recognized certifications.

0
Would love your thoughts, please comment.x
()
x