探索C#之不可变数据类型
作者:网络转载 发布时间:[ 2015/9/7 10:56:44 ] 推荐标签:测试开发技术
不可变优点
集合共享安全,从不被改变
访问集合时,不需要锁集合(线程安全)
修改集合不担心旧集合被改变
书写更简洁,函数式风格。 var list = ImmutableList.Empty.Add(10).Add(20).Add(30);
保证数据完整性,安全性
不可变对象缺点
不可变本身的优点即是缺点,当每次对象/集合操作都会返回个新值。而旧值依旧会保留一段时间,这会使内存有极大开销,也会给GC造成回收负担,性能也比可变集合差的多。
跟string和StringBuild一样,Net提供的不可变集合也增加了批量操作的API,用来避免大量创建对象:
ImmutableList<string> immutable = ImmutableList<string>.Empty;
//转换成可批量操作的集合
var immutable2 = immutable.ToBuilder();
immutable2.Add("xx");
immutable2.Add("xxx");
//还原成不可变集合
immutable = immutable2.ToImmutable();
我们来对比下可变集合、不可变Builder集合、不可变集合的性能,添加新对象1000W次:
比较代码如下:
private static void List()
{
var list = new List<object>();
var sp = Stopwatch.StartNew();
for (int i = 0; i < 1000 * 10000; i++)
{
var obj = new object();
list.Add(obj);
}
Console.WriteLine("可变列表集合:"+sp.Elapsed);
}
private static void BuilderImmutableList()
{
var list = ImmutableList<object>.Empty;
var sp = Stopwatch.StartNew();
var blist= list.ToBuilder();
for (int i = 0; i < 1000 * 10000; i++)
{
var obj = new object();
blist.Add(obj);
}
list=blist.ToImmutable();
Console.WriteLine("不可变Builder列表集合:"+sp.Elapsed);
}
private static void ImmutableList()
{
var list = ImmutableList<object>.Empty;
var sp = Stopwatch.StartNew();
for (int i = 0; i < 1000 * 10000; i++)
{
var obj = new object();
list = list.Add(obj);
}
Console.WriteLine("不可变列表集合:" + sp.Elapsed);
}
另外一个缺点比较有趣,也有不少人忽略。 由于string的不可变特性,所以当我们使用string在保存敏感信息时,需要特别注意。
比如密码 var pwd=”mushroomsir”,此时密码会以明文存储在内存中,也许你稍后会加密置空等,但这都是会生成新值的。而明文会长时间存储在共享域内存中,任何能拿到dump文件的人都可以看到明文,增加了密码被窃取的风险。
当然这不是一个新问题,net2.0提供的有SecureString来进行安全存储,使用时进行恢复及清理。
IntPtr addr = Marshal.SecureStringToBSTR(secureString);
string temp = Marshal.PtrToStringBSTR(addr);
Marshal.ZeroFreeBSTR(addr);
WriteProcessMemory(...)
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11