我在实现 IEnumerable 接口(interface)的对象池中有以下代码。
public IEnumerable<T> ActiveNodes
{
get
{
for (int i = 0; i < _pool.Count; i++)
{
if (_pool[i].AvailableInPool)
{
yield return _pool[i];
}
}
}
}
据我所知(根据 this 问题),这将产生垃圾,因为需要收集 IEnumerable 对象。 _pool 中的任何元素都不会被收集,因为池的目的是保留对所有元素的引用以防止产生垃圾。
谁能建议一种允许对 _pool 进行迭代以便不产生垃圾的方法?
当迭代池时,池中所有具有 AvailableInPool == true 的项目都应该被迭代。顺序无关紧要。
最佳答案
首先,许多人反驳 Olhovsky 说这没什么好担心的。避免收集压力在某些环境的某些应用程序中实际上非常重要。
紧凑型框架垃圾收集器有一个简单的策略;每次分配 1000KB 内存时,它都会触发一次收集。现在假设您正在编写一个在紧凑型框架上运行的游戏,并且物理引擎每次运行时都会产生 1KB 的垃圾。物理引擎通常每秒运行 20 次。所以这是每分钟 1200KB 的压力,嘿,这已经超过了每分钟一次收集仅来自物理引擎。如果收集导致游戏中出现明显的卡顿,那么这可能是 Not Acceptable 。在这种情况下,任何您可以采取的措施来降低收集压力都会有所帮助。
即使我在桌面 CLR 上工作,我自己也是通过艰难的方式学习的。我们在编译器中有一些场景,我们必须避免收集压力,我们正在跳过各种对象池环来做到这一点。奥尔霍夫斯基,我感受到你的痛苦。
那么,回到您的问题,如何在不产生收集压力的情况下迭代池对象的集合?
首先我们来思考下典型场景下为什么会产生采集压力。假设你有
foreach(var node in ActiveNodes) { ... }
逻辑上这分配了两个对象。首先,它分配表示节点序列的可枚举对象(序列)。其次,它分配代表序列中当前位置的枚举器——游标。
在实践中,有时您可以作弊,让一个对象同时表示序列和枚举器,但您仍然分配了一个对象。
我们如何避免这种收集压力?我想到了三件事。
1) 首先不要创建 ActiveNodes 方法。让调用者按索引遍历池,并自行检查节点是否可用。序列就是已经分配的池,游标是一个整数,两者都不会产生新的收集压力。您付出的代价是重复代码。
2) 正如 Steven 所建议的,编译器将采用具有正确公共(public)方法和属性的任何类型;它们不必是 IEnumerable 和 IEnumerator。您可以制作自己的可变结构序列和游标对象,按值传递它们,并避免收集压力。具有可变结构是危险的,但它是可能的。注意 List<T>将此策略用于其枚举器;研究其实现思路。
3) 在堆上正常分配序列和枚举数,并将它们也池化!您已经在采用合并策略,因此没有理由不能合并枚举器。枚举器甚至有一个方便的“重置”方法,通常只抛出一个异常,但您可以编写一个自定义枚举器对象,当它返回到池中时,使用它来将枚举器重置回序列的开头。
大多数对象一次只枚举一次,因此在典型情况下池可以很小。
(现在,当然,您可能会遇到先有鸡还是先有蛋的问题;您打算如何枚举枚举器池?)
关于c# - 允许迭代而不产生任何垃圾,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5486654/
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数
我试图在索引页中创建一个超链接,但它没有显示,也没有给出任何错误。这是我的index.html.erb代码。ListingarticlesTitleTextssss我检查了我的路线,我认为它们也没有问题。PrefixVerbURIPatternController#Actionwelcome_indexGET/welcome/index(.:format)welcome#indexarticlesGET/articles(.:format)articles#indexPOST/articles(.:format)articles#createnew_articleGET/article
我在用Ruby执行简单任务时遇到了一件奇怪的事情。我只想用每个方法迭代字母表,但迭代在执行中先进行:alfawit=("a".."z")puts"That'sanalphabet:\n\n#{alfawit.each{|litera|putslitera}}"这段代码的结果是:(缩写)abc⋮xyzThat'sanalphabet:a..z知道为什么它会这样工作或者我做错了什么吗?提前致谢。 最佳答案 因为您的each调用被插入到在固定字符串之前执行的字符串文字中。此外,each返回一个Enumerable,实际上您甚至打印它。试试
我正在处理旧代码的一部分。beforedoallow_any_instance_of(SportRateManager).toreceive(:create).and_return(true)endRubocop错误如下:Avoidstubbingusing'allow_any_instance_of'我读到了RuboCop::RSpec:AnyInstance我试着像下面那样改变它。由此beforedoallow_any_instance_of(SportRateManager).toreceive(:create).and_return(true)end对此:let(:sport_
如何在ruby中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL
我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha
HashMap中为什么引入红黑树,而不是AVL树呢1.概述开始学习这个知识点之前我们需要知道,在JDK1.8以及之前,针对HashMap有什么不同。JDK1.7的时候,HashMap的底层实现是数组+链表JDK1.8的时候,HashMap的底层实现是数组+链表+红黑树我们要思考一个问题,为什么要从链表转为红黑树呢。首先先让我们了解下链表有什么不好???2.链表上述的截图其实就是链表的结构,我们来看下链表的增删改查的时间复杂度增:因为链表不是线性结构,所以每次添加的时候,只需要移动一个节点,所以可以理解为复杂度是N(1)删:算法时间复杂度跟增保持一致查:既然是非线性结构,所以查询某一个节点的时候
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
我正在使用DMOZ的listofurltopics,其中包含一些具有包含下划线的主机名的url。例如:608609TheOuterHeaven610InformationandimagegalleryofMcFarlane'sactionfiguresforTrigun,Akira,TenchiMuyoandotherJapaneseSci-Fianimations.611Top/Arts/Animation/Anime/Collectibles/Models_and_Figures/Action_Figures612虽然此url可以在网络浏览器中使用(或者至少在我的浏览器中可以使用: