You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求C#中Stack与Heap性能差异的代码示例及研究资料

Stack与Heap性能对比的C#代码示例

一、核心差异说明

  • Stack:用于存储值类型(如int、自定义struct),内存分配/释放仅通过栈指针移动完成,速度极快,但空间有限,由CLR自动管理无需GC介入。
  • Heap:用于存储引用类型(如class、数组),内存分配需查找可用内存块,释放依赖GC回收,速度较慢,但存储空间充裕。

二、性能测试代码

以下代码通过大规模迭代创建值类型(Stack分配)和引用类型(Heap分配),统计两者的耗时差异,同时加入GC回收的额外开销测试:

using System;
using System.Diagnostics;

namespace StackHeapBenchmark
{
    // 栈存储的值类型
    public struct StackValue
    {
        public int Id;
        public string Label; // 注:string为引用类型,实际存储在Heap,但struct实例本身在Stack
    }

    // 堆存储的引用类型
    public class HeapObject
    {
        public int Id;
        public string Label;
    }

    class Program
    {
        static void Main(string[] args)
        {
            const long TestCount = 10_000_000; // 测试迭代次数
            var stopwatch = new Stopwatch();

            // 测试Stack分配性能
            stopwatch.Start();
            for (long i = 0; i < TestCount; i++)
            {
                var stackItem = new StackValue
                {
                    Id = (int)i,
                    Label = $"Stack_{i}"
                };
                // 保留简单操作避免编译器优化
                if (stackItem.Id == TestCount)
                    Console.WriteLine(stackItem.Label);
            }
            stopwatch.Stop();
            Console.WriteLine($"Stack 分配耗时: {stopwatch.ElapsedMilliseconds} ms");

            // 测试Heap分配性能
            stopwatch.Reset();
            stopwatch.Start();
            for (long i = 0; i < TestCount; i++)
            {
                var heapItem = new HeapObject
                {
                    Id = (int)i,
                    Label = $"Heap_{i}"
                };
                // 保留简单操作避免编译器优化
                if (heapItem.Id == TestCount)
                    Console.WriteLine(heapItem.Label);
            }
            stopwatch.Stop();
            Console.WriteLine($"Heap 分配耗时: {stopwatch.ElapsedMilliseconds} ms");

            // 测试Heap分配+GC回收的总开销
            stopwatch.Reset();
            stopwatch.Start();
            for (long i = 0; i < TestCount; i++)
            {
                var heapItem = new HeapObject
                {
                    Id = (int)i,
                    Label = $"Heap_GC_{i}"
                };
            }
            GC.Collect(); // 手动触发GC,模拟内存回收的额外开销
            stopwatch.Stop();
            Console.WriteLine($"Heap 分配+GC回收耗时: {stopwatch.ElapsedMilliseconds} ms");
        }
    }
}

三、测试结果解读

  • 正常情况下,Stack分配的耗时会远低于Heap分配,因为Stack内存操作仅为栈指针的上下移动,无需复杂的内存寻址和对象标记。
  • 当加入GC回收操作后,Heap的总耗时会显著增加——GC需要暂停线程、标记存活对象、清理内存碎片,这些操作都会带来额外性能开销。

四、测试注意事项

  • 编译器可能会对无意义的对象创建进行优化,因此代码中保留了简单的条件判断,避免测试结果失真。
  • 测试结果受硬件配置、CLR版本、系统负载影响,建议多次测试取平均值。

内容的提问来源于stack exchange,提问作者Samiullah Hafiz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 17:57:20