- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
在 C# 中哪个内存效率更高:选项 #1 还是选项 #2?
public void TestStringBuilder()
{
//potentially a collection with several hundred items:
string[] outputStrings = new string[] { "test1", "test2", "test3" };
//Option #1
StringBuilder formattedOutput = new StringBuilder();
foreach (string outputString in outputStrings)
{
formattedOutput.Append("prefix ");
formattedOutput.Append(outputString);
formattedOutput.Append(" postfix");
string output = formattedOutput.ToString();
ExistingOutputMethodThatOnlyTakesAString(output);
//Clear existing string to make ready for next iteration:
formattedOutput.Remove(0, output.Length);
}
//Option #2
foreach (string outputString in outputStrings)
{
StringBuilder formattedOutputInsideALoop = new StringBuilder();
formattedOutputInsideALoop.Append("prefix ");
formattedOutputInsideALoop.Append(outputString);
formattedOutputInsideALoop.Append(" postfix");
ExistingOutputMethodThatOnlyTakesAString(
formattedOutputInsideALoop.ToString());
}
}
private void ExistingOutputMethodThatOnlyTakesAString(string output)
{
//This method actually writes out to a file.
System.Console.WriteLine(output);
}
câu trả lời hay nhất
有几个答案温和地建议我摆脱困境并自己弄清楚,所以下面是我的结果。我认为这种情绪通常与该网站的主旨背道而驰,但如果您希望做对某事,您不妨……:)
我修改了选项 #1 以利用 @Ty 建议使用 StringBuilder.Length = 0 而不是 Remove 方法。这使得两个选项的代码更加相似。现在的两个区别是 StringBuilder 的构造函数是在循环中还是在循环外,选项 #1 现在使用 Length 方法来清除 StringBuilder。这两个选项都设置为运行一个包含 100,000 个元素的 outputStrings 数组,以使垃圾收集器做一些工作。
几个答案提供了查看各种 PerfMon 计数器等的提示,并使用结果来选择一个选项。我做了一些研究,最终使用了我工作中使用的 Visual Studio Team Systems Developer 版本的内置 Performance Explorer。我找到了一个多部分系列的第二篇博客文章,解释了如何设置它 đây .基本上,您连接一个单元测试以指向您要分析的代码;通过向导和一些配置;并启动单元测试分析。我启用了 .NET 对象分配和生命周期指标。很难为这个答案格式化的分析结果,所以我把它们放在最后。如果您将文本复制并粘贴到 Excel 中并稍微修改一下,它们将是可读的。
选项 #1 的内存效率最高,因为它使垃圾收集器做的工作少一点,并且它为 StringBuilder 对象分配的内存和实例比选项 #2 少一半。对于日常编码,选择选项 #2 非常合适。
如果您仍在阅读,我问这个问题是因为选项 #2 会使经验丰富的 C/C++ 开发人员的内存泄漏检测器变得弹道。如果在重新分配之前未释放 StringBuilder 实例,则会发生巨大的内存泄漏。当然,我们 C# 开发人员不担心这些事情(直到他们跳起来咬我们)。感谢大家!!
ClassName Instances TotalBytesAllocated Gen0_InstancesCollected Gen0BytesCollected Gen1InstancesCollected Gen1BytesCollected
=======Option #1
System.Text.StringBuilder 100,001 2,000,020 100,016 2,000,320 2 40
System.String 301,020 32,587,168 201,147 11,165,268 3 246
System.Char[] 200,000 8,977,780 200,022 8,979,678 2 90
System.String[] 1 400,016 26 1,512 0 0
System.Int32 100,000 1,200,000 100,061 1,200,732 2 24
System.Object[] 100,000 2,000,000 100,070 2,004,092 2 40
======Option #2
System.Text.StringBuilder 200,000 4,000,000 200,011 4,000,220 4 80
System.String 401,018 37,587,036 301,127 16,164,318 3 214
System.Char[] 200,000 9,377,780 200,024 9,379,768 0 0
System.String[] 1 400,016 20 1,208 0 0
System.Int32 100,000 1,200,000 100,051 1,200,612 1 12
System.Object[] 100,000 2,000,000 100,058 2,003,004 1 20
关于c# - 使用 StringBuilder Remove 方法比在循环中创建新的 StringBuilder 方法更节省内存吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/266923/
我正在使用 .remove() 方法删除一个 html 元素,同时对于这个元素,我有一个事件处理程序,但它没有被触发。为什么会这样呢?这是jsFiddle和代码:HTML Delete I'm goi
所以我尝试从另一篇文章中编写此代码: while(fscanf(orderFile," %49[^;];%d; %49[^\n]",fileName,&seconds,timeValue) == 3)
我正在阅读 Nicolai M.Josuttis 撰写的“The C++ STL. A Tutorial and References”一书,在专门介绍 STL 算法的一章中,作者陈述如下:如果你调用
是否有一种简单的机制来确定 DownloadManager remove() 何时完成,因为它看起来是部分异步的。该函数几乎立即返回下载表中已删除的条目计数,但实际的文件系统管理似乎被插入了某个后台线
我愿意: getActionBarToolbar().removeView(logoImage); getActionBarToolbar().addView(logoImage, lp); 我得到:
我有类(class)评论一对多关系。在类(class)表中有 id 和 title 列。在 Review 表中,有 id、comment 和 course_id,其中“course_id”作为指向类(
我在 stackoverflow 上阅读了不同的答案,了解如何销毁 wigdet/jQueryObject 并取消绑定(bind)其上的所有事件。 这就是我的想法。 $('选择器').remove()
我有一个由一个线程填充的 byte[] 列表,然后我有另一个线程正在从该列表中读取并通过网络发送项目。 每次我读取线程 2 中的项目时,我都想将其从内存中清除。但是因为我正在使用线程,如果我使用 .r
就算法而言,从连续数组中删除一组元素可以分两部分有效地完成。 将所有不删除的元素移到数组的前面。 将数组标记得更小。 这可以在 C++ 中使用 erase-remove 习惯用法来完成。 vector
我尝试删除包含在 map 中渲染的制造商的 View 。当我单击按钮时,事件 click .ver 被激活,但没有任何反应,并且我收到以下错误:Uncaught TypeError: undefine
场景: 使用 jQuery 2.0.1 构建的应用程序。 您的团队更喜欢原生 JavaScript。 选项有jQuery .remove()和 ChildNode.remove() . 您需要删除节点
最初我有一个像这样的删除功能: function ViewWorkflowDetail(btn, workflowId) { $("#workflowDetailPanel").remov
我正在编写 C++ 代码来解决 Leetcode 中的这个问题:https://leetcode.com/problems/remove-element/ Given an array nums an
根据太阳, "Iterator.remove is the only safe way to modify a collection during iteration; the behavior is
众所周知,从 std::vector 中完全删除所需项的一种好方法是 erase-remove idiom . 如以上链接中所述(截至本文发布日期),在代码中,erase-remove 习惯用法如下所
我在 HashSet 上调用 Iterator.remove() 时遇到问题。 我有一组带有时间戳的对象。在将新项目添加到集合之前,我会遍历集合,识别该数据对象的旧版本并将其删除(在添加新对象之前)。
这段代码: Collection col = new ArrayList(); col.add("a"); col.add("b"); col.add("c");
我试图通过在下面输入来卸载 conda 环境基础, conda env remove -n base 正如我所建议的那样,我尝试通过使用来停用基地 conda deactivate base 我再次尝
我已经对我的 IOS 应用程序进行了质量扫描分析。我收到以下警告: The binary has Runpath Search Path (@rpath) set. In certain cases
这个问题已经有答案了: Properly removing an Integer from a List (8 个回答) 已关闭 4 年前。 我是java新手。看起来很简单,但我不明白为什么会发生这种
Tôi là một lập trình viên xuất sắc, rất giỏi!