当前位置: 首页 > 面试题库 >

在类似StringBuilder的C模块中增加多少缓冲区?

左丘阳晖
2023-03-14
问题内容

在C语言中,我正在研究一个管理字节缓冲区的“类”,该类允许将任意数据附加到末尾。我现在正在研究自动调整大小,因为底层数组使用调用填充了realloc。这对曾经使用Java或C#的任何人都应该有意义StringBuilder。我了解如何调整大小。但是,有没有人提供任何建议,并提供了有关每次调整大小增加缓冲区
多少的 建议?

显然,要在浪费的空间和过多的重新分配调用之间进行权衡(这可能导致过多的复制)。我看过一些建议加倍的教程/文章。如果用户设法提供一个很好的初始猜测,那似乎是浪费。是否值得尝试将平台的对齐大小取整为两倍或整数倍的幂?

有人知道引擎盖下的Java或C#是什么吗?


问题答案:

在C#中,用于增长StringBuilder使用的内部缓冲区的策略已随时间而改变。

解决此问题有三种基本策略,它们具有不同的性能特征。

第一个基本策略是:

  • 制作字符数组
  • 当您的空间不足时,请为常数k创建一个包含k个其他字符的新数组。
  • 将旧阵列复制到新阵列,然后孤立旧阵列。

该策略存在许多问题,最明显的问题是,如果要构建的字符串非常大,则及时变为O(n
2)。假设k是一千个字符,最后一个字符串是一百万个字符。您最终将字符串重新分配为1000、2000、3000、4000 …,因此复制了1000 +
2000 + 3000 + 4000 + … + 999000个字符,总共复制了5000亿个字符!

该策略具有很好的属性,即“浪费”的内存量由k限制。

实际上,由于该n平方问题,很少使用此策略。

第二个基本策略是

  • 制作一个数组
  • 当您的空间不足时,请为常数k创建一个多k%个字符的新数组。
  • 将旧阵列复制到新阵列,然后孤立旧阵列。

k%通常是100%;如果是,则将其称为“装满时加倍”策略。

该策略具有很好的特性,即其 摊销 成本为O(n)。再次假设最后一个字符串是一百万个字符,并且您从一千开始。您以1000、2000、4000、8000
…复制,最终复制1000 + 2000 + 4000 + 8000 … + 512000个字符,总共复制了大约一百万个字符;好多了。

该策略具有以下特性: 无论您选择什么百分比 ,摊销成本都是线性的

这种策略有很多缺点, 有时复制操作会非常昂贵 ,并且 您可能在未使用的内存中浪费最终字符串长度的k%

第三种策略是创建一个数组的链表,每个数组的大小为k。当现有数组溢出时,将分配一个新数组并将其附加到列表的末尾。

该策略具有很好的特性:没有操作特别昂贵,总浪费的内存由k限制,您不需要能够定期在堆中定位大块。不利的一面是,最终将事物转换为字符串可能会很昂贵,因为链接列表中的数组可能位置不佳。

.NET框架中的字符串生成器过去曾使用过双重填充策略。现在,它使用了阻止链接列表策略。



 类似资料:
  • 问题内容: 今天,我了解到,将stdout设置为terminal并在不同情况下进行缓冲时,它是行缓冲的。因此,在正常情况下,如果我使用printf()而不以“ \ n”结尾,则仅在缓冲区已满时才在屏幕上打印它。如何获得此缓冲区的大小,这有多大? 问题答案: 实际大小由各个实现定义;该标准并没有规定最小大小(无论如何,基于我已经能够找到的大小)。没有关于如何确定缓冲区大小的线索。 编辑 章节: 7.

  • 我正在阅读有关流的信息,发现我们可以使用setvbuf()函数来控制流......它写的是在行缓冲模式中,当遇到换行符时流将数据发送到文件中,在无缓冲状态下没有缓冲......所以我写了以下代码...... 所以我认为,因为这些是无缓冲流,所以输入应该在我写入屏幕后立即发送到标准输出。。。但程序在写入每一行后等待我按enter键,然后屏幕上只显示输出(由于fwrite)。。。我的问题是,当这些是无

  • 问题内容: 构造函数中的缓冲区大小是什么意思? 当我编写程序时: 输出: 然后,缓冲区大小是什么意思,正如我希望的那样,它只能读取两个字符。但事实并非如此。 问题答案: 顾名思义,缓冲输入。这意味着它会在将输入源传递给您之前从输入源读取到缓冲区。此处的缓冲区大小是指其缓冲的字节数。 从大多数来源读取输入非常慢。仅2个字节的缓冲区将损害性能,因为您的程序很可能大部分时间都在等待输入。缓冲区大小为2时

  • 问题内容: 我正在尝试创建一个异步通道,并且一直在查看http://golang.org/ref/spec#Making_slices_maps_and_channels。 缓冲区大小为10是什么意思?缓冲区大小具体代表/限制了什么? 问题答案: 缓冲区大小是在没有发送阻塞的情况下可以发送到通道的元素数。默认情况下,通道的缓冲区大小为0(可通过来获得此值)。这意味着每个发送都会阻塞,直到另一个go

  • ByteArrayOutputStream(int size)-创建一个新的字节数组输出流,具有指定大小的缓冲区容量(以字节为单位)。 ByteArrayOutputStream()在默认情况下有32个字节的缓冲区,这就是Apache Commons有完全相同的类org.Apache.Commons.io.output.ByteArrayOutputStream的原因:“最初的实现一开始只分配32

  • 问题内容: 读取文件太大而无法容纳缓冲区时,出现致命错误。 要么, RangeError:“ size”参数不得大于Function.Buffer.allocUnsafe(buffer.js:209:3)的2147483647 如果我尝试分配1GB缓冲区,则会遇到同样的致命错误, Node.js Buffer类实例的最大大小是多少? 问题答案: V8中类型化数组的最大长度当前设置为以下值,具体取决