繁体   English   中英

使用(合并)后清除对象变量c#

[英]Clear object variables after use (pooling) c#

我正在研究一种池算法,该算法采用已分配的对象并回收其分配以供以后使用。 但是,回收对象的问题之一例如是:

 someObject obj = pool.alloc(); //gives me a new object if no previous allocations, If an allocation has been recycled, returns a previous allocation
 obj.someVariable = "foo";
 pool.recycle(obj);

上面的代码将采用现有分配并将其保存,这样,在我要拥有另一个someObject的情况下,我就不必分配任何额外的内存。 但是,以下内容会引起问题:

 someObject obj = pool.alloc(); //gives me the above allocation
 obj.otherVariable = "bar";
 obj.dump();

结果,我将得到以下结果:

  someVariable = foo
  otherVariable = bar

上面的方法产生了一个问题。 如果我由于某种原因(或其他原因)拥有一种不使用对象内部某些变量的算法,则旧值可能会导致不必要的行为。 我仔细研究了一下是否有某种方法可以再次调用默认构造函数(不好的主意),而C#(谢天谢地)似乎不允许您这样做。 但是,我想知道是否有某种方法可以使用反射来做到这一点? 另外,清除对象中的变量是否违反避免使用malloc(新)的目的? 换句话说,如果我花时间清理变量,性能提升会变得最小吗? 我试图自学成才,因此,任何批评和建议都将不胜感激!

这是查看池的一种方法:

只有在重用某些复杂的设置工作时才真正需要进行池化,而这些工作可以通过检索已经存在的对象来避免。 例如,对象池的最著名应用程序之一是“数据库连接”的形式。

池适用于数据库连接(DBConns),因为1)DBConn可以通过连接字符串轻松标识; 和2)建立DBConn需要花费大量的工作和时间。 通过匹配连接字符串来完成简单的标识-如果两个连接字符串相同,则它们建立的连接也应该相同。 另外,一旦有了连接字符串,就可能需要数百毫秒来查找服务器地址,为其打开套接字,进行身份验证并建立连接。 这意味着池对于数据库连接非常有效,因为释放连接时,下次可为同一连接字符串请求连接时可以重新使用该池。

.NET运行时环境非常擅长快速分配对象并释放它们,因此您不会遇到内存问题。 如果您担心的只是内存使用或分配速度,请不要担心。 您无法通过自行清零内存来击败编译器的性能。 但是,如果您的对象具有一些复杂而冗长的设置,而可以通过从池中检索现有对象来避免这种设置,那么您会发现一些好处。

池化的另一个很好的例子是电子游戏中的粒子系统。 您只有数百个粒子必须创建,经历生命周期并被销毁,只有在旧粒子死亡后才可以创建新粒子。 典型的粒子系统将创建X个对象作为数组,并具有Reset()函数,该函数将死对象作为新创建的粒子在原始位置恢复生命。 再次起作用的原因是因为可以轻松识别粒子,并且可以进行设置(为图形系统提供纹理,放置位置等)。

您的应用程序既具有“简单匹配识别”功能又可以避免漫长的设置过程? 如果不是,则每次分配新的对象-我敢打赌,您不会看到任何性能下降。

编辑:从性能的角度,让我们在这里看:

重置变量= O(N)分配语句; 使用反射可以大大增加

实例化一个新对象=一个malloc调用,一个构造函数调用; 复杂度级别取决于构造函数代码和内存碎片。

使用反射来重置变量是可行的,但是您必须事先知道O(N)的赋值比malloc和构造函数要快。 对于数据库连接,我知道满足条件。 但这对您的游泳池是真的吗?

编辑:从下面的评论中,您可能确实找到了适当合并的情况。 如果是这种情况,我建议理想的方法是为池中的任何类创建一个Reset()函数。 尝试创建一个定义功能Reset()IPoolable接口。 然后,对于池中的每个类,定义Reset()函数,以便将所有关键变量归零。 因为它可以编译,所以不会产生反射开销,并且您可以维护特定于对象的优化,这是动态代码无法实现的。

对于池,将池类定义为MyPool<IPoolable> 然后,只要检索到以前回收的对象,就可以在将其交还给调用者之前对其调用Reset()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM