C#将bool重新解释为字节/整数(无分支) [英] C# reinterpret bool as byte/int (branch-free)

查看:207
本文介绍了C#将bool重新解释为字节/整数(无分支)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C#中是否有可能将 bool 转换为 byte int (或者实际上是任何整数类型)没有分支

Is it possible in C# to turn a bool into a byte or int (or any integral type, really) without branching?

换句话说,这不是 足够好:

In other words, this is not good enough:

var myInt = myBool ? 1 : 0;

我们可能会说我们想重新解释 bool 作为基础 byte ,最好使用尽可能少的指令。目的是避免分支预测失败,如此处

We might say we want to reinterpret a bool as the underlying byte, preferably in as few instructions as possible. The purpose is to avoid branch prediction fails as seen here.

推荐答案

也许可行吗? (想法来源)

using System;
using System.Reflection.Emit;

namespace ConsoleApp10
{
    class Program
    {
        static Func<bool, int> BoolToInt;
        static Func<bool, byte> BoolToByte;

        static void Main(string[] args)
        {
            InitIL();

            Console.WriteLine(BoolToInt(true));
            Console.WriteLine(BoolToInt(false));
            Console.WriteLine(BoolToByte(true));
            Console.WriteLine(BoolToByte(false));

            Console.ReadLine();
        }

        static void InitIL()
        {
            var methodBoolToInt = new DynamicMethod("BoolToInt", typeof(int), new Type[] { typeof(bool) });
            var ilBoolToInt = methodBoolToInt.GetILGenerator();
            ilBoolToInt.Emit(OpCodes.Ldarg_0);
            ilBoolToInt.Emit(OpCodes.Ldc_I4_0); //these 2 lines
            ilBoolToInt.Emit(OpCodes.Cgt_Un); //might not be needed
            ilBoolToInt.Emit(OpCodes.Ret);

            BoolToInt = (Func<bool, int>)methodBoolToInt.CreateDelegate(typeof(Func<bool, int>));

            var methodBoolToByte = new DynamicMethod("BoolToByte", typeof(byte), new Type[] { typeof(bool) });
            var ilBoolToByte = methodBoolToByte.GetILGenerator();
            ilBoolToByte.Emit(OpCodes.Ldarg_0);
            ilBoolToByte.Emit(OpCodes.Ldc_I4_0); //these 2 lines
            ilBoolToByte.Emit(OpCodes.Cgt_Un);  //might not be needed
            ilBoolToByte.Emit(OpCodes.Ret);

            BoolToByte = (Func<bool, byte>)methodBoolToByte.CreateDelegate(typeof(Func<bool, byte>));

        }
    }
}

基于每次发射的Microsoft文档。

based on microsoft documentation of each emit.


  1. 将参数加载到内存(布尔值)中

  2. 加载到内存int = 0的值

  3. 比较是否有任何参数大于该值(可能在此处分支?)

  4. 如果为true,则返回1 0

  1. load the parameter in memory (the boolean)
  2. load in memory a value of int = 0
  3. compare if any the parameter is greater than the value (branching here maybe?)
  4. return 1 if true else 0

第2行和第3行可以删除,但是返回值可以不是0/1

line 2 and 3 can be removed but the return value could be something else than 0 / 1

就像我在开始时所说的,该代码是从另一个响应中获取的,这似乎是可以的,但在进行基准测试时似乎很慢,查找 .net DynamicMethod慢找到使它更快的方法

like i said in the beginning this code is taken from another response, this seem to be working yes but it seem slow while being benchmarking, lookup .net DynamicMethod slow to find way to make it "faster"

您可以使用。boolean中的GetHashCode

true将返回1的int和false 0

true will return int of 1 and false 0

然后可以 var myByte =(byte)bool.GetHashCode();

you can then var myByte = (byte)bool.GetHashCode();

这篇关于C#将bool重新解释为字节/整数(无分支)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆