sln Asked:2023-12-18 16:24:06 +0800 CST2023-12-18 16:24:06 +0800 CST 2023-12-18 16:24:06 +0800 CST 获取一个块有多困难?为什么在 C# 中将数据复制到 StringBuilder 块中? 772 我理解 中的字符串生成器C#,但我无法理解两件事: 为什么它的实现代码中写的是获取chunk的算术复杂度是O(N*N)or O(N)?它不应该一直存在吗O(log(N))?O(log(N))搜索所需的块 +O(1)通过块内的索引进行检索。 我们这里讨论的将数据传输到新块的操作是什么?为什么要迁移数据?当填充一块时,是否可以简单地将不适合的内容放入2两倍大的新块中? c# 1 个回答 Voted Best Answer CrazyElf 2023-12-18T16:59:31+08:002023-12-18T16:59:31+08:00 我读了代码。我想我可以回答。 块列表: первый <- ... <- предыдущий <- текущий <- следующий <- ... <- последний <- |у нас есть|нужно найти| ... |начинаем с конца| 中的块StringBuilder是一个单链表,并且仅存在从下一个块到前一个块以及到列表末尾的链接(显然,为了在必要时轻松地从列表末尾删除元素)。因此,为了按直接顺序迭代块(即,这是您正在解析的代码段),您需要在每个迭代步骤中从最后一个到第一个迭代块以搜索当前块,以便找到下一个迭代所需的下一个块。对于chunk数<8,迭代时,正是从尾部开始使用这种排序的列表,得到搜索的整体复杂度,但是O(N*N)对于超过88个chunks的情况,临时使用一个辅助数组(直到搜索完成)完成)用块的索引创建,因此获得复杂度O(N)(有了索引,您不需要在每个迭代步骤中重新迭代所有块来查找下一个块;它只是通过索引从临时索引数组中获取),但这种方法需要额外的O(N)临时内存。 为什么要迁移数据?当填充一块时,不是可以简单地将不适合的东西放入一个大 2 倍的新块中吗? 事实上,您将数据放入新块中而不是传输数据吗?这是同一件事,只是用不同的说法。或者你的意思是旧的块应该保留在原处,并且仅对于不适合的部分,创建一个新的块来放置数据?显然,他们不想最终得到太多的块。这里有一个永恒的权衡。要么有很少的块,但在调整块大小时进行复制,要么在不复制以前的内容的情况下制作许多块,但对于每个块,您需要一个额外的链接,并且绕过这些块需要更长的时间,并且在复制所有块时需要更长的时间终于来了ToString()。因此,如果我理解正确的话,他们会尝试保持较小的块大小8000(这样它就不会去Large Object Heap),并且在此大小内,块会尽可能长地增长(通过分配增加大小的块并复制其中的内容)。从起始尺寸开始16。
我读了代码。我想我可以回答。
块列表:
中的块
StringBuilder
是一个单链表,并且仅存在从下一个块到前一个块以及到列表末尾的链接(显然,为了在必要时轻松地从列表末尾删除元素)。因此,为了按直接顺序迭代块(即,这是您正在解析的代码段),您需要在每个迭代步骤中从最后一个到第一个迭代块以搜索当前块,以便找到下一个迭代所需的下一个块。对于chunk数<8,迭代时,正是从尾部开始使用这种排序的列表,得到搜索的整体复杂度,但是O(N*N)
对于超过8
8个chunks的情况,临时使用一个辅助数组(直到搜索完成)完成)用块的索引创建,因此获得复杂度O(N)
(有了索引,您不需要在每个迭代步骤中重新迭代所有块来查找下一个块;它只是通过索引从临时索引数组中获取),但这种方法需要额外的O(N)
临时内存。事实上,您将数据放入新块中而不是传输数据吗?这是同一件事,只是用不同的说法。或者你的意思是旧的块应该保留在原处,并且仅对于不适合的部分,创建一个新的块来放置数据?显然,他们不想最终得到太多的块。这里有一个永恒的权衡。要么有很少的块,但在调整块大小时进行复制,要么在不复制以前的内容的情况下制作许多块,但对于每个块,您需要一个额外的链接,并且绕过这些块需要更长的时间,并且在复制所有块时需要更长的时间终于来了
ToString()
。因此,如果我理解正确的话,他们会尝试保持较小的块大小8000
(这样它就不会去Large Object Heap
),并且在此大小内,块会尽可能长地增长(通过分配增加大小的块并复制其中的内容)。从起始尺寸开始16
。