C#中创建或访问数据容器的最优方式:两种List实现的性能对比
两种List创建与访问方式的性能对比分析
先看你给出的代码示例:
public class TestClass { private static List<String> stringList1 = new List<String> { "string1", "string2", "string3", "string4"}; public void TestFunc(String str) { if (stringList1.Contains(str)) //1st way of accessing list { //do something } if (getList2().Contains(str)) //2nd way of accessing list { //do something } } private List<String> getList2() { return new List<String> { "string1", "string2", "string3", "string4"}; } }
从性能维度考量,第一种方式(使用静态成员stringList1)完全优于第二种方式,具体分析如下:
一、运行速度
- 第一种方式:
stringList1是静态成员,类首次加载时就完成初始化,之后每次调用TestFunc都是直接访问已存在的列表,Contains操作仅需遍历已有元素集合。 - 第二种方式:每次调用
getList2()都会新建List实例,还要完成元素初始化与赋值,之后才能执行Contains检查。相当于每次调用都多了对象创建、内存分配的额外开销,调用次数越多,速度差距越明显。
二、内存占用
- 第一种方式:程序运行全程只会存在一个
stringList1实例,内存占用固定,且字符串元素从字符串池共享,不会重复占用内存。 - 第二种方式:每调用一次
getList2()就会在堆上分配新的List内存,这些临时List用完后需等待GC回收。若TestFunc被高频调用,会产生大量短期垃圾对象,不仅占用额外内存,还会触发更频繁的垃圾回收,进一步拖慢程序效率。
额外优化建议
如果这个集合固定不变,且仅需做存在性检查,建议把List换成HashSet<string>:
private static readonly HashSet<string> stringSet1 = new HashSet<string> { "string1", "string2", "string3", "string4" };
因为HashSet.Contains的时间复杂度是O(1),比List的O(n)遍历快得多,更适合频繁做存在性判断的场景。
内容的提问来源于stack exchange,提问作者Madz
相关产品推荐
相关产品推荐

