C#对象比较和内存分配
我的同事为大多数基本类型提供了10个不同的函数<代码>字符串,C#对象比较和内存分配,c#,C#,我的同事为大多数基本类型提供了10个不同的函数字符串,int,double,bool 我对1000万个项目进行了测试,在我的机器上更改值比检查它们是否不同然后更改它们快40%左右。我测试了1000万个不需要更改的项目和1000万个需要更改的项目 当问他为什么他有这些功能,而不是仅仅改变价值观,因为它更便宜。他告诉我这是为了防止内存分配和内存碎片。因此,如果对象是相同的,它可以保留在相同的内存地址中,因此速度更快 public static void CopyIfDifferent(ref str
int
,double
,bool
我对1000万个项目进行了测试,在我的机器上更改值比检查它们是否不同然后更改它们快40%左右。我测试了1000万个不需要更改的项目和1000万个需要更改的项目
当问他为什么他有这些功能,而不是仅仅改变价值观,因为它更便宜。他告诉我这是为了防止内存分配和内存碎片。因此,如果对象是相同的,它可以保留在相同的内存地址中,因此速度更快
public static void CopyIfDifferent(ref string vValueToCopyTo, string vValueToCopyFrom)
{
if (!ValuesAreEqual(vValueToCopyTo, vValueToCopyFrom))
{
vValueToCopyTo = vValueToCopyFrom;
}
}
public static bool ValuesAreEqual(string vValue1, string vValue2)
{
if (vValue1 == null && vValue2 == null)
{
return true;
}
if (vValue1 == null || vValue2 == null)
{
return false;
}
return vValue1 == vValue2;
}
使用函数
Utils.CopyIfDifferent(ref GroupIDFK, item.GroupIDFK);
我的问题是。在更改之前检查值是否比仅更改值更好?如果是,为什么?是的,我想交换指针(只是更改)比检查差异更有效,因为检查需要更多的时间
即使是最快的检查,也就是检查引用是否相等,引用交换也需要(或多或少)相同的时间。关于防止内存分配和内存碎片,它对于值类型是无用的,因为引用没有变化。变量有自己的内存,其内容被替换,因此没有新的内存分配 IMHO在设置值类型之前检查相等性的唯一原因是:
- 您需要引发一些事件(如OnChange)
- 设置该值将启动一个复杂的操作,如将其保存到数据库或刷新缓存
- 该值类型确实经常设置
using System;
using System.Diagnostics;
namespace ConsoleApplication1
{
public class Program
{
public static void Main(string[] args)
{
Process proc = Process.GetCurrentProcess();
Console.WriteLine("GetTotalMemory:{0} PrivateMemorySize64:{1} press enter to continue", GC.GetTotalMemory(true), proc.PrivateMemorySize64);
Console.ReadLine();
const int testCount = 1000000000;
var stopWatch = new Stopwatch();
int a = 2456;
int b = 2456;
stopWatch.Start();
for (int i = 0; i < testCount; i++)
{
CopyIfDifferent(ref a, b);
}
stopWatch.Stop();
Console.WriteLine("int equal CopyIfDifferent ElapsedMilliseconds:{0}", stopWatch.ElapsedMilliseconds);
Console.WriteLine("GetTotalMemory:{0} PrivateMemorySize64:{1} press enter to continue", GC.GetTotalMemory(true), proc.PrivateMemorySize64);
GC.Collect();
Console.ReadLine();
stopWatch.Restart();
for (int i = 0; i < testCount; i++)
{
a = b;
}
stopWatch.Stop();
Console.WriteLine("int equal assignment ElapsedMilliseconds:{0}", stopWatch.ElapsedMilliseconds);
Console.WriteLine("GetTotalMemory:{0} PrivateMemorySize64:{1} press enter to continue", GC.GetTotalMemory(true), proc.PrivateMemorySize64);
Console.ReadLine();
string c = "dfsgdgdfg";
string d = "dfsgdgdfg";
stopWatch.Restart();
for (int i = 0; i < testCount; i++)
{
CopyIfDifferent(ref c, d);
}
stopWatch.Stop();
Console.WriteLine("string equal CopyIfDifferent ElapsedMilliseconds:{0}", stopWatch.ElapsedMilliseconds);
Console.WriteLine("GetTotalMemory:{0} PrivateMemorySize64:{1} press enter to continue", GC.GetTotalMemory(true), proc.PrivateMemorySize64);
Console.ReadLine();
stopWatch.Restart();
for (int i = 0; i < testCount; i++)
{
c = d;
}
stopWatch.Stop();
Console.WriteLine("string equal assignment ElapsedMilliseconds:{0}", stopWatch.ElapsedMilliseconds);
Console.WriteLine("GetTotalMemory:{0} PrivateMemorySize64:{1} press enter to continue", GC.GetTotalMemory(true), proc.PrivateMemorySize64);
Console.ReadLine();
int e = 2456;
int f = 3465464;
stopWatch.Restart();
for (int i = 0; i < testCount; i++)
{
CopyIfDifferent(ref e, f);
}
stopWatch.Stop();
Console.WriteLine("int different CopyIfDifferent ElapsedMilliseconds:{0}", stopWatch.ElapsedMilliseconds);
Console.WriteLine("GetTotalMemory:{0} PrivateMemorySize64:{1} press enter to continue", GC.GetTotalMemory(true), proc.PrivateMemorySize64);
Console.ReadLine();
stopWatch.Restart();
for (int i = 0; i < testCount; i++)
{
e = f;
}
stopWatch.Stop();
Console.WriteLine("int different assignment ElapsedMilliseconds:{0}", stopWatch.ElapsedMilliseconds);
Console.WriteLine("GetTotalMemory:{0} PrivateMemorySize64:{1} press enter to continue", GC.GetTotalMemory(true), proc.PrivateMemorySize64);
Console.ReadLine();
string g = "dfsgdgdfg";
string h = "gdfhfghfghfghf";
stopWatch.Restart();
for (int i = 0; i < testCount; i++)
{
CopyIfDifferent(ref g, h);
}
stopWatch.Stop();
Console.WriteLine("string different CopyIfDifferent ElapsedMilliseconds:{0}", stopWatch.ElapsedMilliseconds);
Console.WriteLine("GetTotalMemory:{0} PrivateMemorySize64:{1} press enter to continue", GC.GetTotalMemory(true), proc.PrivateMemorySize64);
Console.ReadLine();
stopWatch.Restart();
for (int i = 0; i < testCount; i++)
{
g = h;
}
stopWatch.Stop();
Console.WriteLine("string different assignment ElapsedMilliseconds:{0}", stopWatch.ElapsedMilliseconds);
Console.WriteLine("GetTotalMemory:{0} PrivateMemorySize64:{1} press enter to continue", GC.GetTotalMemory(true), proc.PrivateMemorySize64);
Console.ReadLine();
}
public static void CopyIfDifferent(ref string vValueToCopyTo, string vValueToCopyFrom)
{
if (!ValuesAreEqual(vValueToCopyTo, vValueToCopyFrom))
{
vValueToCopyTo = vValueToCopyFrom;
}
}
public static void CopyIfDifferent(ref int vValueToCopyTo, int vValueToCopyFrom)
{
if (vValueToCopyTo != vValueToCopyFrom)
{
vValueToCopyTo = vValueToCopyFrom;
}
}
public static bool ValuesAreEqual(string vValue1, string vValue2)
{
if (vValue1 == null && vValue2 == null)
{
return true;
}
if (vValue1 == null || vValue2 == null)
{
return false;
}
return vValue1 == vValue2;
}
}
}
使用系统;
使用系统诊断;
命名空间控制台应用程序1
{
公共课程
{
公共静态void Main(字符串[]args)
{
Process proc=Process.GetCurrentProcess();
WriteLine(“GetTotalMemory:{0}privateMorysize64:{1}按enter键继续”,GC.GetTotalMemory(true),proc.privateMorysize64);
Console.ReadLine();
const int testCount=100000000;
var stopWatch=新秒表();
INTA=2456;
int b=2456;
秒表。开始();
对于(int i=0;i// Compare strings: case sensitive, current culture
if (String.Equals(vValueToCopyTo, vValueToCopyFrom))
vValueToCopyTo = vValueToCopyFrom;
// Compare strings: case insensitive and invariant culture
if (String.Equals(vValueToCopyTo, vValueToCopyFrom, StringComparison.OrdinalIgnoreCase))
vValueToCopyTo = vValueToCopyFrom;
if (a == b)
a = b;
if (a != b) // != instead of ==
a = b;
public static void CopyIfDifferent(ref string vValueToCopyTo, string vValueToCopyFrom)
{
if (!ValuesAreEqual(vValueToCopyTo, vValueToCopyFrom))
{
vValueToCopyTo = vValueToCopyFrom;
}
}
string s1 = "One";
string s2 = "Two";
CopyIfDifferent(ref s2, s1);
s2 = s1;
public static void CopyIfDifferent(ref int vValueToCopyTo, int vValueToCopyFrom)
{
if (!ValuesAreEqual(vValueToCopyTo, vValueToCopyFrom))
{
vValueToCopyTo = vValueToCopyFrom;
}
}
public static bool ValuesAreEqual(int vValue1, int vValue2)
{
return vValue1 == vValue2;
}