【问题标题】:Is there a string type with 8 BIT chars?有 8 位字符的字符串类型吗?
【发布时间】:2011-06-22 10:58:02
【问题描述】:

我需要在 RAM 中存储很多字符串。但它们不包含特殊的 unicode 字符,它们都只包含来自“ISO 8859-1”的字符,即一个字节。

现在我可以转换每个字符串,将其存储在内存中,然后将其转换回以与 .Contains() 和类似的方法一起使用,但这会产生开销(在我看来)并且速度很慢。

是否有一个快速可靠的字符串类,并提供原始字符串类的一些方法,如 .Contains()?

我需要这个来在内存中存储更多的字符串,而使用更少的 RAM。或者有其他方法吗?

更新:

感谢您的 cmets 和您的回答。

我有一个存储字符串的类。然后通过一个方法调用,我需要确定我是否已经在内存中拥有该字符串。如果它们在列表中,我有大约 1000 个字符串要弄清楚。总计数亿。 字符串的平均大小约为 20 个字符。真正关心我的是 RAM。

我什至想过压缩几百万个字符串并将这些包存储在内存中。但是每次我需要访问这些值时,我都需要对其进行解压缩。

我也尝试过使用HashSet,但所需的内存量更大。

我不需要真正的价值。只是想知道该值是否在列表中。因此,如果有一个哈希值可以做到这一点,那就更好了。但我发现的所有内容都需要比纯字符串更多的内存。

目前没有进一步国际化的计划。所以我会在需要处理的时候处理它:-)

我不知道使用数据库是否可以解决它。我不需要获取任何东西,只需知道该值是否存储在类中。我需要快速完成这项工作。

【问题讨论】:

  • 您可以将它们存储为byte[] 吗?然后就可以使用Array的Contains方法了。
  • 克里斯你确定使用普通的 unicode 字符串会影响性能,因为你必须加载太多的字符串?!我有点惊讶,如果您真的必须加载数百或数千 MB 的字符串,那么无论您使用 ASCII/ANSI 还是 Unicode,您的应用程序可能设计得并不正确。如果字符串太多,也许数据库方法会很好。
  • 散发着过早优化的味道。当您突然需要国际化您的应用程序时会发生什么?
  • 如果您需要存储大约 1000 个平均长度为 20 个字符的字符串,您的 1 字节字符的净总量约为 20KB,2 字节的字符约为 40KB。 这不是问题。使用 String 类,继续前进。
  • 对不起Lasse,我不是在说1000个字符串,我是在数亿个计算。

标签: c# string char


【解决方案1】:

检查 string.Intern 方法,它可以帮助你:

http://www.yoda.arachsys.com/csharp/strings.html

http://en.csharp-online.net/CSharp_String_Theory%E2%80%94String_intern_pool

但是看看你的要求,我认为你在设计它。你有 1000 个字符串,20 个字符 = 1000 * 20 * 2 = 40,000 字节,内存并不多。

如果你真的有很多,请将其存储在带有索引的数据库中。这将比普通程序员所能想到的要快得多。

【讨论】:

  • 是的,这是一个很大的数量,每秒 1000 个字符串来验证它们是否存储在类中。存储了数亿个字符串。你的文件是真的吗?他们写道:“至少在当前的实现中,字符串占用 20+(n/2)*4 个字节(将 n/2 的值向下舍入),其中 n 是字符串中的字符数。”
  • 您建议使用什么数据库(适用于 windows,内存占用少,每秒可以对字符串进行 1000 次包含比较)?
  • 您的原始描述没有明确问题的大小。我仍然认为您尝试转换字符串时走错了路。尝试 SQL Server,否则我认为您需要扩展或扩展。将负载分散到多个服务器上,也许使用 Azure。
【解决方案2】:

您不太可能因此获得任何显着的表现。不过,如果需要节省内存,这种策略可能比较合适。

  • 要将string 转换为byte[],请使用Encoding.Default.GetBytes()[1]

  • 要将byte[] 转换回string 以进行显示或其他基于字符串的处理,请使用Encoding.Default.GetString()

  • 如果您使用在 stringbyte[] 上定义的扩展方法,您可以使您的代码看起来更好。或者,您可以将byte[] 包装在包装类型中并将方法放在那里。将此包装器类型设为struct,而不是class,否则会导致额外的堆分配,这是您要避免的。

不过,我想警告您 — 您正在放弃在应用程序中使用 Unicode 的能力。每次你认为你需要这样做时,你通常应该让所有的警钟响起。最好以这样一种方式构建代码,以便在内存大小增加且内存消耗不再是问题时可以轻松返回使用 string


[1]Encoding.Default 返回正在运行的操作系统的当前 8 位代码页。英语 Windows 上的默认设置是 Windows-1252,这正是您想要的。对于俄语 Windows,它将是 Windows-1251(西里尔文)等。

【讨论】:

    【解决方案3】:

    根据 cmets,基本上是个坏主意。如果你必须这样做,byte[] 是你的朋友。 .NET 中没有面向字节的字符串类。

    【讨论】:

      猜你喜欢
      • 2016-10-18
      • 1970-01-01
      • 2013-01-20
      • 2011-04-11
      • 1970-01-01
      • 2019-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多