将字节数组转换为 int 的更快方法

2023-11-22

有没有比更快的方法BitConverter.ToInt32将字节数组转换为 int 值?


我实际上尝试了几种不同的方法将四个字节转换为 int:

  1. BitConverter.ToInt32(new byte[] { w, x, y, z }, 0);
  2. BitConverter.ToUInt32(new byte[] { w, x, y, z }, 0);
  3. b = new byte[] { w, x, y, z }; BitConverter.ToInt32(b, 0);
  4. b = new byte[] { 1, 2, 3, 4, 5, 6, 7, w, x, y, z }; BitConverter.ToInt32(b, 7);
  5. w | (x << 8) | (y << 16) | (z << 24);
  6. b[0] | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);

我在发布 (x86) 版本中运行了 10^9 次迭代,而不是在 2.5 GHz 的调试器下运行Core i7笔记本电脑。这是我的结果(请注意,不使用的方法BitConverter明显更快):

test1: 00:00:15.5287282 67305985
test2: 00:00:15.1334457 67305985
test3: 00:00:08.0648586 67305985
test4: 00:00:11.2307059 67305985
test5: 00:00:02.0219417 67305985
test6: 00:00:01.6275684 67305985

您可以得出一些结论:

  • test1 表明,在我的笔记本电脑上,很难让转换速度慢于 15ns,但我不想说这对任何人来说都足够快了。 (每秒调用次数是否需要超过60M次?)
  • test2表明使用uint代替int节省少量时间。我不知道为什么,但我认为它小到足以成为实验误差。
  • test3 显示创建新字节数组的开销 (7ns) 与调用该函数几乎一样多,但仍然比从旧数组创建新数组要快。
  • test4 表明,进行未对齐的数组访问ToInt32增加开销(3ns)
  • test5 表明,从局部变量中提取 4 个字节并自行组合它们比调用快几倍ToInt32.
  • test6 表明,从数组中提取 4 个字节实际上比从函数参数中提取要快一些!我怀疑这是由于 CPU 流水线或缓存效应造成的。

最快的 test6 的运行时间仅为空循环(未显示)的两倍。换句话说,执行每次转换所需的时间不到 1ns。祝你好运,任何有用的计算都比这更快!

这是我的测试程序:

using System;

namespace BitConverterTest
{
    class Program
    {
        const int iters = 1000000000;
        static void Main(string[] args)
        {
            test1(1, 2, 3, 4);
            test2(1, 2, 3, 4);
            test3(1, 2, 3, 4);
            test4(1, 2, 3, 4);
            test5(1, 2, 3, 4);
            test6(1, 2, 3, 4);
        }

        static void test1(byte w, byte x, byte y, byte z)
        {
            int res = 0;
            var timer = System.Diagnostics.Stopwatch.StartNew();
            for (int i = 0; i < iters; i++)
                res = BitConverter.ToInt32(new byte[] { w, x, y, z }, 0);
            Console.WriteLine("test1: " + timer.Elapsed + " " + res);
        }

        static void test2(byte w, byte x, byte y, byte z)
        {
            uint res = 0;
            var timer = System.Diagnostics.Stopwatch.StartNew();
            for (int i = 0; i < iters; i++)
                res = BitConverter.ToUInt32(new byte[] { w, x, y, z }, 0);
            Console.WriteLine("test2: " + timer.Elapsed + " " + res);
        }

        static void test3(byte w, byte x, byte y, byte z)
        {
            int res = 0;
            var timer = System.Diagnostics.Stopwatch.StartNew();
            var b = new byte[] { w, x, y, z };
            for (int i = 0; i < iters; i++)
                res = BitConverter.ToInt32(b, 0);
            Console.WriteLine("test3: " + timer.Elapsed + " " + res);
        }

        static void test4(byte w, byte x, byte y, byte z)
        {
            int res = 0;
            var timer = System.Diagnostics.Stopwatch.StartNew();
            var b = new byte[] { 1, 2, 3, 4, 5, 6, 7, w, x, y, z };
            for (int i = 0; i < iters; i++)
                res = BitConverter.ToInt32(b, 7);
            Console.WriteLine("test4: " + timer.Elapsed + " " + res);
        }

        static void test5(byte w, byte x, byte y, byte z)
        {
            int res = 0;
            var timer = System.Diagnostics.Stopwatch.StartNew();
            var b = new byte[] { w, x, y, z };
            for (int i = 0; i < iters; i++)
                res = w | (x << 8) | (y << 16) | (z << 24);
            Console.WriteLine("test5: " + timer.Elapsed + " " + res);
        }

        static void test6(byte w, byte x, byte y, byte z)
        {
            int res = 0;
            var timer = System.Diagnostics.Stopwatch.StartNew();
            var b = new byte[] { w, x, y, z };
            for (int i = 0; i < iters; i++)
                res = b[0] | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
            Console.WriteLine("test6: " + timer.Elapsed + " " + res);
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将字节数组转换为 int 的更快方法 的相关文章

  • 即使进程确实存在,为什么 Process.WaitForExit 也会抛出“无进程”异常?

    我有一个包含以下代码的 Windows 服务 public static void ExtractTextInner string source string destination ProcessStartInfo startInfo n
  • JNI 将 Char* 2D 数组传递给 JAVA 代码

    我想从 C 代码通过 JNI 层传递以下指针数组 char result MAXTEST MAXRESPONSE 12 12 8 3 29 70 5 2 42 42 在java代码中我写了以下声明 public static native
  • 如何填充 ToolStripComboBox?

    我发现它很难将数据绑定到ToolStripComboBox 好像没有这个ValueMember and DisplayMember特性 怎么绑定呢 访问toolstripcombobox中包装的组合框并访问其ValueMember Disp
  • 使用 LINQ to SQL 时避免连接超时的最佳实践

    我需要知道在 net 应用程序中使用 LINQ to SQL 时避免连接超时的最佳实践 特别是在返回时IQueryable
  • 在Linux中,找不到框架“.NETFramework,Version=v4.5”的参考程序集

    我已经设置了 Visual studio 来在我的 Ubuntu 机器上编译 C 代码 我将工作区 我的代码加载到 VS 我可以看到以下错误 The reference assemblies for framework NETFramewo
  • 为什么可以通过ref参数修改readonly字段?

    考虑 class Foo private readonly string value public Foo Bar ref value private void Bar ref string value value hello world
  • 在视口中查找 WPF 控件

    Updated 这可能是一个简单或复杂的问题 但在 wpf 中 我有一个列表框 我用一个填充数据模板从列表中 有没有办法找出特定的数据模板项位于视口中 即我已滚动到其位置并且可以查看 目前我连接到了 listbox ScrollChange
  • Arrayadapter.getcount 空点异常

    我得到以下堆栈跟踪 下面是完整的副本 这几乎没有或根本没有表明大型应用程序中出现错误时的位置 并且用户反馈除了 崩溃 之外什么也没有 我能做些什么来进一步查明这一点吗 java lang NullPointerException at an
  • Foursquare - OAuth 身份验证 - .Net 示例

    是否有关于如何使用 Oauth 向 Foursquare 进行身份验证的示例 这里有一个关于如何将 OAuth 与 Foursquare 结合使用的非常好的工作流程摘要 http developer foursquare com docs
  • 使用 Amazon SQS 的 .net 应用程序示例

    我正在寻找一个示例 Net 应用程序 该应用程序会持续检查 Amazon SQS 是否有新消息 并在发现新消息时执行一项操作并将其从队列中删除 我的目标是让一个在 EC2 上运行的应用程序监视我的 SQS 队列中的新消息 当找到一条消息时
  • 将值添加到数组的最有效方法

    假设我有一个大小为N where N gt 0 是否有一种更有效的方法可以不需要 O N 1 步骤来添加到数组中 在代码中 本质上 我目前正在做的是 function prependArray value oldArray var newA
  • 我的 .NET 库列表中缺少 System.Windows.Data

    您好 我想使用 System Windows Data IValueConverter 但是当我尝试在 VS2010 中添加对 System Windows Data 的引用时 我只看到 System Windows Forms 和 Sys
  • 为标签生成成员:我有什么理由应该这样做?

    我在这里读过另一篇文章 因此 如果可能的话 您不应该为标签生成成员 我想知道有什么潜力缺点到这会是 我说的好处是性能提高 对吗 还要别的吗 我有一个带有 100 个标签的 winform 应用程序 不产生成员有什么好处 还是只有在 Web
  • MongoDb 注册类映射

    我有以下代码 我希望 MiscellaneousData 覆盖抽象的 MiscellaneousDataBase 然而 IdMemberMap 总是出现空值 使用独立的 正常 类是可行的 if BsonClassMap IsClassMap
  • 在 C 中通过引用传递数组

    我是 C 新手 我有一个疑问 由于 C 函数创建其参数的本地副本 我想知道为什么以下代码按预期工作 void function int array array 0 4 array 1 5 array 2 6 int main int arr
  • 用 C# 编写插件或插件框架

    我正在用 C 编写一个 Addin 框架 我想知道如何使 Addin 可以卸载而无需重新启动应用程序 我听说过 AppDomains 但是它们是如何工作的呢 外接程序是否可以添加可扩展性类并通过接口在主应用程序域中调用 并且仍然可卸载并调用
  • 使用远程管理凭据将文件复制到远程计算机

    我正在使用 C 我需要能够将一组文件复制到大约 500 台不同的计算机上 我已成功地使用 LogonUser 方法来模拟具有复制文件所需权限的域帐户 文件的目标路径类似于 远程计算机 C SomeFolder 我的问题是 有没有办法做到这一
  • 如何将 UDF 中的结构或类数组返回到数据帧列值中?

    d ID 1 pID 1000 startTime 2018 07 02T03 34 20 endTime 2018 07 03T02 40 20 ID 1 pID 1000 startTime 2018 07 02T03 45 20 en
  • 结构体指针的动态数组

    我必须使用以下代码块来完成学校作业 严格不进行任何修改 typedef struct char firstName char lastName int id float mark pStudentRecord pStudentRecord
  • 在 Javascript 中减少/分组数组

    基于this https stackoverflow com a 40774906 3254598例如 我想以稍微不同的方式按对象进行分组 结果应该如下 key audi items make audi model r8 year 2012

随机推荐