【发布时间】:2009-01-26 16:22:20
【问题描述】:
我倾向于将字符串的长度设为 2 的幂(16、32、64)。对于字符串类型的对象(例如字符串变量、字符串集合或字符串类型数据库中的列)执行此操作是否有任何优化好处?这是在 .net/sql 服务器环境中。
【问题讨论】:
我倾向于将字符串的长度设为 2 的幂(16、32、64)。对于字符串类型的对象(例如字符串变量、字符串集合或字符串类型数据库中的列)执行此操作是否有任何优化好处?这是在 .net/sql 服务器环境中。
【问题讨论】:
由于 .NET 字符串不是以 null 结尾的,因此您必须非常聪明才能实际使用每个字符串中的完美字符数。
String message = "hello world!!!!!"; // Exactly 16 chars
此外,字符串大小的二次方仅在您的实现使用“malloc”执行内存分配时才重要。这是一种内存分配策略,它表示“如果它们的大小都为 2 次方,那么我的单个内存碎片将更适合堆,浪费的空间更少”。
但是 .NET 不使用 malloc 来分配内存。相反,所有堆内存都是通过递增堆指针来分配的。稍后 GC 释放内存时,会进行 heap compaction,这样所有新的内存都来自最后,永远不需要在碎片堆中寻找一小块内存。
【讨论】:
对于数据库中的列:注意 SQL 的 8kb 数据页。行越小,每个数据页上可以容纳的行就越多。每个数据页中可以容纳的行越多,读取这些行的速度就越快(更少的页面意味着更少的 IO)。这适用于表和索引。
这里有更多来自Wikipedia 的信息。
【讨论】:
没有。你会用你不使用的字符串块做什么,因为它只是填充。与尝试对齐字符串所可能节省的任何成本相比,这种浪费的成本将是巨大的。它非常怀疑这样的长度是否有任何好处。
【讨论】:
C#/.Net 中的字符串是不可变的,因此在构造字符串时没有必要(或任何方式)预先分配空间来容纳更多字符。如果您附加到一个字符串,您会得到一个新字符串,它会创建新空间来保存整个新字符串并且不会重新分配。就 SQL 列而言,如果您事先知道字符串的确切长度 (char(N)) 或使用不同的字符数据 (varchar(N)),则应该将它们设为字符串的确切长度,并将 N 选为合适的最大值。我认为将这些保持为 2 的幂没有任何意义——当您创建 varchar 列时,SSMS 默认为 50,因此显然 Microsoft 也没有。
预分配可能产生影响的一个地方是 StringBuilder 或预分配集合的大小。同样,它的大小应该以不必调整大小为目标,但如果已知,则接近其实际使用情况。如果不知道,那么要么跳过初始尺寸,要么让它足够大以容纳大多数情况。
【讨论】:
这是一个优化可能没有那么有益的领域。我会根据需要定义长度,然后在需要时返回并优化长度。我想你会发现对字符串长度的默认处理就足够了。
【讨论】:
没有。二次幂大小优化来自数据库时代的曙光,与数据在磁盘和内存中的对齐方式有关。今天,这是一种没有优势的退化行为。
【讨论】: