Ascii 字节数组转 Int32 或 Double

发布于 2024-08-26 20:46:41 字数 911 浏览 14 评论 0原文

我正在重写 alibrary,并要求使其完全免分配。目标是在应用程序的启动阶段完成后拥有 0 个集合。

以前,有很多这样的调用:

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

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

这就是我所做的

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# 库函数已经以更优化的方式执行此操作吗?或者进行改进以使上述运行速度更快(可能会在一天中被调用数百万次)。谢谢!

I'm re-writing alibrary with a mandate to make it totally allocation free. The goal is to have 0 collections after the app's startup phase is done.

Previously, there were a lot of calls like this:

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

Which I believe is allocating a string. I couldn't find a C# library function that would do the same thing automatically. I looked at the BitConverter class, but it looks like that is only if your Int32 is encoded with the actual bytes that represent it. Here, I have an array of bytes representing Ascii characters that represent an Int32.

Here's what I did

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;
}

Does anyone know of a C# library function that already does this in a more optimal way? Or an improvement to make the above run faster (its going to be called millions of times during the day probably). Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

奢华的一滴泪 2024-09-02 20:46:41

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

该代码将更容易理解为:

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

它与您的行执行相同的操作

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

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

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

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

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

Millions of times per day shouldn't be a problem - I'd expect that to be able to run hundreds of thousands of times per second. Personally I'd rewrite the above to only declare "temp" within the loop (and get rid of the Pascal-cases local variable names - urgh) but it should be okay.

The code would be more immediately understandable as:

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

which does the same as your

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

line, but in a simpler way (IMO). They should behave exactly the same way.

On a general note, trying to write C# without any allocations is pretty harsh, and fights against the way the language and framework are designed. Do you believe this is actually a reasonable requirement? Admittedly I've heard about it being the way some games are written in managed code... but it does seem a bit odd.

Of course, you're going to allocate an exception if the bytes are inappropriate...

EDIT: Note that your code doesn't allow for negative numbers. Is that okay?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文