【问题标题】:Ascii Bytes Array To Int32 or DoubleAscii 字节数组到 Int32 或 Double
【发布时间】:2010-03-26 12:21:12
【问题描述】:

我正在重写库,以使其完全免费分配。目标是在应用启动阶段完成后拥有 0 个集合。

以前有很多这样的电话:

Int32 foo = Int32.Parse(ASCIIEncoding.ASCII.GetString(bytes, start, length));

我相信这是分配一个字符串。我找不到可以自动执行相同操作的 C# 库函数。我查看了 BitConverter 类,但看起来只有当您的 Int32 使用代表它的实际字节进行编码时。在这里,我有一个字节数组,表示代表 Int32 的 Ascii 字符。

这就是我所做的

public static Int32 AsciiBytesToInt32(byte[] bytes, int start, int length)
{
     Int32 Temp = 0;
     Int32 Result = 0;
     Int32 j = 1;

     for (int i = start + length - 1; i >= start; i--)
     {
          Temp = ((Int32)bytes[i]) - 48;

          if (Temp < 0 || Temp > 9)
          {
               throw new Exception("Bytes In AsciiBytesToInt32 Are Not An Int32");
          }

          Result += Temp * j;
          j *= 10;
     }

     return Result;
}

有谁知道 C# 库函数已经以更优化的方式做到了这一点?或改进以使上述运行更快(它可能会在白天被调用数百万次)。谢谢!

【问题讨论】:

  • 如果说托管代码优于传统代码的原因之一就是分配内存的非常成本。刻意避免它就像是为了参加奥运会而左脚摔倒一样。
  • 分配内存很便宜;垃圾收集不是。创建大量垃圾最终可能会将相对短命的对象推入 Gen2 堆,这通常是值得避免的。
  • 同意。我们正在努力减少收藏。我们肯定会看到一些需要 100 毫秒的 Gen2 集合。我猜这些短命的字符串不是一个大问题,它们应该很快被收集起来。但它们并不难去除。如果我们只是说:在应用程序的持续运行阶段没有分配,它可以更容易地追踪真正的大量分配来自哪里。

标签: c# .net ascii byte int32


【解决方案1】:

每天数百万次应该不是问题 - 我希望它能够每秒运行数十万次。就我个人而言,我会重写上面的内容,只在循环中声明“temp”(并去掉 Pascal-cases 局部变量名 - 呃),但应该没问题。

下面的代码更容易理解:

int digit = bytes[i] - '0';

和你的一样

Temp = ((Int32)bytes[i]) - 48;

行,但以更简单的方式 (IMO)。它们的行为方式应该完全相同。

总的来说,尝试在没有任何分配的情况下编写 C# 是相当苛刻的,并且与语言和框架的设计方式作斗争。您认为这实际上是一个合理的要求吗?诚然,我听说有些游戏是用托管代码编写的……但这确实有点奇怪。

当然,如果字节不合适,你会分配一个异常......

编辑:请注意,您的代码不允许使用负数。可以吗?

【讨论】:

  • 他也不处理溢出。
  • 感谢您的回复。关于底片和溢出的要点。这些整数大部分应该很小,但负数可能是个问题。
  • 我不应该说没有分配。我真的只是说我们试图在应用程序的启动阶段预先分配几乎所有东西。这是一个应用程序,其中 Gen2 集合的 100 毫秒冻结可能会产生影响,因此我们正在尝试遵循此处概述的设计实践:microsoft.com/downloads/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-27
  • 2017-05-04
相关资源
最近更新 更多