- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
在 C 中,我正在研究一个管理字节缓冲区的“类”,允许将任意数据附加到末尾。我现在正在研究当底层数组填满时使用调用 realloc
自动调整大小。这对于曾经使用过 Java 或 C# StringBuilder
的人来说应该是有意义的。我了解如何调整大小。但是有没有人对每次调整大小时增加多少缓冲区有任何建议,并提供了理由?
显然,在浪费的空间和过多的 realloc 调用(这可能会导致过多的复制)之间需要权衡取舍。我看过一些建议加倍的教程/文章。如果用户设法提供一个好的初始猜测,那似乎很浪费。是否值得尝试四舍五入到平台上对齐大小的两倍或倍数?
有谁知道 Java 或 C# 在幕后做了什么?
最佳答案
在 C# 中,用于增加 StringBuilder 使用的内部缓冲区的策略已随时间发生变化。
解决这个问题的基本策略有3种,它们具有不同的性能特点。
第一个基本策略是:
这个策略有很多问题,其中最明显的是如果正在构建的字符串非常大,它的时间复杂度为 O(n2)。假设 k 是一千个字符,最终的字符串是一百万个字符。您最终将字符串重新分配到 1000、2000、3000、4000,...,因此复制了 1000 + 2000 + 3000 + 4000 + ... + 999000 个字符,总计复制了 5000 亿个字符!
这个策略有一个很好的特性,即“浪费”的内存量以 k 为界。
由于 n 平方问题,在实践中很少使用这种策略。
第二个基本策略是
k% 通常为 100%;如果是,则这称为“满时加倍”策略。
这个策略有一个很好的特性,即它的摊销 成本是 O(n)。再次假设最终字符串是一百万个字符,而您从一千个字符开始。您以 1000、2000、4000、8000、... 进行复制,最终复制了 1000 + 2000 + 4000 + 8000 ... + 512000 个字符,总计复制了大约一百万个字符;好多了。
无论您选择什么百分比,该策略的摊销成本都是线性的。
这种策略有一些缺点,有时复制操作非常昂贵,您可能会在未使用的内存中浪费高达 k% 的最终字符串长度 .
第三种策略是创建一个数组链表,每个数组的大小为 k。当您溢出现有数组时,会分配一个新数组并将其附加到列表的末尾。
这个策略有一个很好的特性,即没有操作特别昂贵,总浪费的内存受 k 限制,并且您不需要定期在堆中定位大块。它的缺点是最终将事物转换为字符串可能会很昂贵,因为链表中的数组可能具有较差的局部性。
.NET Framework 中的字符串生成器过去使用双倍策略;它现在使用 block 链表策略。
关于c# - 在类似 StringBuilder 的 C 模块中增加多少缓冲区?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10196942/
公共(public)类TestMyStringBuilderII { public static void main(String[] args) { StringBuilder sb = n
我们都知道字符串是不可变的而StringBuilder是可变的。正确的。那么为什么它的方法会返回一个 StringBuilder 对象。它们不应该都是 void 方法吗? 为什么会这样 public
当我读到 equals() 方法用于比较 java 中的字符串是否相等但是当我运行这段代码时我得到输出 false 。为什么? public class TestStringBuilder { pu
我收到一份模型列表。模型的数量可能很大。这个模型有一堆属性,其中任何一个都可能是null。 我需要根据模型的属性为每个模型构建一个字符串。如果 property == null,那么我会在结果字符串中
我写了一些代码,其中有很多字符串创建。为了尽量避免一遍又一遍地创建昂贵的字符串,我使用了 java StringBuilder 类。 我的代码有点像这样: public String createSt
这个问题在这里已经有了答案: 关闭10年前。 Possible Duplicate: StringBuilder vs String concatenation in toString() in Ja
类 StringBuilder 定义了四个构造函数,它们都不接受 StringBuilder,但以下编译: StringBuilder sb = new StringBuilder(new Strin
我正在努力在我的代码中使用 StringBuilder,而不是 String使代码在所有解析和连接过程中具有时间效率。 但是当我查看它的源代码时,substring() 方法AbstractStrin
我想知道 StringBuilder,我有一个问题希望社区能够解释。 让我们忘掉代码的可读性,哪些是更快,为什么? StringBuilder.Append: StringBuilder sb = n
这个问题在这里已经有了答案: Single exclamation mark in Kotlin (6 个回答) Example of when should we use run, let, app
我已经附加了一些带有一些字符的 strBuild 并将该 strBuild 放入 stringBuildArr 中。然后在strBuild上调用java.lang.StringBuilder.dele
在 C# 中哪个内存效率更高:选项 #1 还是选项 #2? public void TestStringBuilder() { //potentially a collection with
当使用 StringBuilder.ToString() 时,我遇到了 OutOfMemory 异常。因为我的字符串需要很大的空间。这就是为什么我需要一种方法(也许通过流式传输)来让它工作。 这是我的
这个问题已经有答案了: What's the difference between instance method reference types in Java 8? (3 个回答) 已关闭 7 年
这个问题在这里已经有了答案: What's the difference between instance method reference types in Java 8? (3 个答案) 关闭
最近的 question came up关于使用 String.Format()。我的部分回答包括使用 StringBuilder.AppendLine(string.Format(...)) 的建议
在 SO 上看到一个关于连接字符串的问题后,我做了一些测试,了解到在 foreach 中连接字符串比使用 for 循环和使用数组中的索引慢。由于对数组进行绑定(bind)检查,for 循环不应该变慢吗
我的问题是如果我有时在同一个字符串上使用多线程 字符串不会被替换。(我在记事本上写了这个,所以语法可能是 错误) 使用 System.Thread ...当然还有其他 class .... {
如果我创建一个不可变类。所有字段都必须是最终的。如果我像这样使用 stringbuilder final StringBuilder s = new StringBuilder("你好"); ,那么
是否可以配置 Java StringBuilder类在每次调用之间追加一个新行以追加? 最佳答案 我不认为 StringBuilder内置了该功能。既然你不能只是扩展它,你可以尝试使用装饰器模式...
我是一名优秀的程序员,十分优秀!