【发布时间】:2013-04-18 19:23:17
【问题描述】:
如何实现基于单字节的字符串?
应用程序使用大量单词。
单词来自 SQL,是 varchar(单字节)。
每个单词也有 Int32 ID。
将单词下载到:
Dictionionary<Int32,string>
为了性能。
问题是字典太大,会出现内存不足异常。
我们最终会拆分数据。
该应用程序如此频繁地访问列表,以至于无法为每个请求访问 SQL。
数据库已经非常活跃。
动态分页进出字典不是一个选项 - 它绑定到 ListView 并且使用虚拟化效果很好。
单词只在晚上加载 - 用户只需要一个静态列表。
他们使用这些词来搜索和处理其他数据,但他们不处理这些词。
既然是 char 就可以实现一个基于单字节的单词:
public class StringByte1252 : Object, IComparable, IComparable<StringByte1252>
{
static Encoding win1252 = Encoding.GetEncoding("Windows-1252");
public Int32 ID { get; private set; }
public byte[] Bytes { get; private set; }
public string Value { get { return win1252.GetString(Bytes); } }
public Int32 Length { get { return Bytes.Length; } }
public int CompareTo(object obj)
{
if (obj == null)
{
return 1;
}
StringByte1252 other = obj as StringByte1252;
if (other == null)
{
throw new ArgumentException("A StringByte1252 object is required for comparison.", "obj");
}
return this.CompareTo(other);
}
public int CompareTo(StringByte1252 other)
{
if (object.ReferenceEquals(other, null))
{
return 1;
}
return string.Compare(this.Value, other.Value, StringComparison.OrdinalIgnoreCase);
}
public override bool Equals(Object obj)
{
//Check for null and compare run-time types.
if (obj == null || !(obj is StringByte1252)) return false;
StringByte1252 item = (StringByte1252)obj;
return (this.Bytes == item.Bytes);
}
public override int GetHashCode() { return ID; }
public StringByte1252(Int32 id, byte[] bytes) { ID = id; Bytes = bytes; }
}
上面的方法有效,但它并不比内存效率更高
Dictionionary<Int32,string>
基于 Int16 字符的字典实际上使用的内存略少。
我哪里做错了?
字节数组占用的空间是否超过字节总和?
有没有办法实现单字节字符串?
【问题讨论】:
-
如果你使用
List<byte>而不是String会发生什么? -
@DanPichelman 我该如何列出
? -
单词的平均长度是多少?您的代码为每个字符串分配两个对象,而字符串只分配一个。因此,您的代码只会在长字符串中领先。
-
Jon Skeet 有一篇文章全面讨论了这些确切问题:Of memory and strings
-
长度为 8 时,每个对象的开销和每个字典条目的开销都大于实际的字符数据。
标签: .net string character-encoding