size = (size + (size << 1))>>1;
-使用不错的编译器,您可以将其写为(size * 3)/2
,并且仍应编译为快速代码。在C中,我正在研究一个管理字节缓冲区的“类”,允许将任意数据附加到末尾。我现在正在研究自动调整大小,因为底层数组使用对realloc
的调用来填充。这对曾经使用Java或C#StringBuilder
的任何人都应该有意义。我了解如何调整大小。但是,有人对多少每次调整大小后增加缓冲区有任何建议,并提供了理由吗?
显然,要在浪费的空间和过多的重新分配调用之间进行权衡(这可能导致过多的复制)。我看过一些建议加倍的教程/文章。如果用户设法提供一个很好的初始猜测,那似乎是浪费。是否值得尝试将平台上的对齐大小的两倍或整数取整?
有人知道引擎盖下的Java或C#是什么吗?
在C#中,用于增长StringBuilder使用的内部缓冲区的策略已随着时间而改变。
有三种解决此问题的基本策略,它们具有不同的性能特征。
第一个基本策略是:
此策略有很多问题,最明显的是,如果要构建的字符串非常大,则及时变为O(n 2)。假设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%
。NET框架中的字符串生成器,曾经使用过双重填充策略;它现在使用阻止链接列表策略。
size = (size + (size << 1))>>1;
-使用不错的编译器,您可以将其写为(size * 3)/2
,并且仍应编译为快速代码。[我似乎想起了几年前在Usenet上的一次对话,当时Dinkumware的PJ Plauger(也许是Pete Becker)说,他们进行的测试比以往任何时候都更广泛,并且得出了相同的结论( ,例如,其C ++标准库中std::vector
的实现使用1.5)。
有人教我总是将数组加倍或减半。如果您确实没有关于大小或最大值的提示,则乘以2可确保您长时间拥有大量容量,并且除非您在资源受限的系统上工作,否则最多分配两倍的空间不会太可怕了此外,将事物保持为2的幂可以使您使用移位和其他技巧,并且底层分配通常为2的幂。
[请查看以下链接,以了解如何在Java的JDK11的StringBuilder中完成此操作,尤其是suresureCapacityInternal方法。https://java-browser.yawk.at/java/11/java.base/java/lang/AbstractStringBuilder.java#java.lang.AbstractStringBuilder%23ensureCapacityInternal%28int%29
此实现的默认容量为16,默认容量为 最大容量为Int32.MaxValue。
StringBuilder对象可以分配更多内存来存储字符 当实例的值被放大并且容量为 相应地进行了调整。例如,Append,AppendFormat, 确保功能,插入和替换方法可以扩大 一个实例。
分配的内存量是特定于实现的,并且 异常(ArgumentOutOfRangeException或OutOfMemoryException) 如果所需的内存量大于最大值,则会引发 容量。
基于其他.NET框架,我建议每次达到当前容量时将其乘以1.1。如果需要额外的空间,只需具有与EnsureCapacity
等效的字符,它将手动将其扩展为所需的大小。
List<List<string>>
列表。class StringBuilder
{
private List<List<string>> list;
public Append(List<string> listOfCharsToAppend)
{
list.Add(listOfCharsToAppend);
}
}
这样,您只维护列表列表并在
demand上分配内存,而不是提前分配内存。
此实现的默认容量为16,默认容量为 最大容量为Int32.MaxValue。
List<List<string>>
列表。