English 中文(简体)
在C#没有分行的情况下,我如何重新解释装ing/int?
原标题:How do I reinterpret bool as byte/int without branching in C#?

在C#中,能否将<条码>bool <>/code>变成<条码>逐项或<条码>>(或任何有机类型,实际上)而不分部分<>?

In other words, a ternary is not good enough:

var myInt = myBool ? 1 : 0;   // could compile to a branch

我们可以说,我们希望重新解释《<条码>bool作为背后<条码>的<条码>,最好尽量少用指示。 目的是避免分支预测失败,见


为论证起见,请假设“bool”已作为1 0/1存在于户籍簿登记册或记忆中,而不只是作为比较结果而形成FLAGS。 多数现代的《国际投资协议》确实有零敲碎打的渠道,从一对一对一或一对一对,因此,我们可以希望C#使用。 或<代码>bool 刚来自<代码>x<y,我们要force/em>。 汇编者将其编成册,而不是将<代码>+count=我的Int改为count++周围的一个分支。

最佳回答
问题回答

通常的C#相当于“再解释”的,是用你想要重新解释的那类领域界定“/code”。 这种做法在大多数情况下都是有效的。 在你看来,这样做是为了:

[StructLayout(LayoutKind.Explicit)]
struct BoolByte
{
    [FieldOffset(0)]
    public bool Bool;
    [FieldOffset(0)]
    public byte Byte;
}

然后,你可以做这样的事情:

BoolByte bb = new BoolByte();
bb.Bool = true;
int myInt = bb.Byte;

请注意,你只需要一度启动变量,然后可以像你一样制定<条码>Bool并检索<条码>Byte。 这种做法应当与涉及不安全守则、呼吁方法等的任何办法一样或更好,特别是在处理任何部门预测问题上。

必须指出,如果你能够读到<条码>bool,作为<条码>,则当然任何人均可将write a <条码>bool/code>作为<条码>的,以及实际的<条码>int。 <代码>bool 缩略语 或不得<代码>1。 可在技术上:any 非零价值。

尽管如此,这将使法典更加难以维持。 由于对“<>真实<><>代码/代码>价值实际上看不出的保证,而且仅仅因为增加了复杂性。 极难陷入现实世界的景象,而这种情景却因你再次问世的错失行为而受到困扰。 即使你有合法的现实世界榜样,但可以辩称,它会以其他方式得到更好的解决。 确切的备选办法取决于具体的实际世界实例,但一个例子可能是,以允许按特定条件进行批量处理而不是对每个要素进行测试的方式保存数据。

我强烈建议不要做这样的事情,直到你能够证明现实世界问题,并且已经用尽了其他更加直观和可以维持的选择。

这里的解决办法比我所希望的更符合(而且大概是更多的指示),但实际上直接解决这一问题,即重新解释。

自www.net Core 2.1, we have some reinterpret methods available in MemoryMarshal. 我们可以将我们的<条码>bool作为<条码>ReadOnlySpan<bool>处理,然后我们可将其作为<条码>处理。 阅读:Span<byte>。 从那以后,它就算是单面价值。

var myBool = true;
var myBoolSpan = MemoryMarshal.CreateReadOnlySpan(ref myBool, length: 1);
var myByteSpan = MemoryMarshal.AsBytes(myBoolSpan);
var myByte = myByteSpan[0]; // =1

或许可以做到这一点? 来源:

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

        }
    }
}

根据每卷缩略微文件编制。

  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。

如同在开始时从另一项答复中讲过的那样,这似乎正在发挥作用,但似乎在基准、检索<代码>.net DynamicMethod 时进展缓慢,以找到办法使其“faster”成为“faster”

you maybe use the .GetHashCode of the boolean?

真实情况是1岁和0岁。

之后,您可读到var myByte = (byte)bool。 GetHashCode();

(修订) 《系统源代码》。

bool b = true;
byte by = ((IConvertible)b).ToByte(null)

看看大会,我们就没有获得任何额外的分支。

    public int M(bool b) {
        byte by = ((IConvertible)b).ToByte(null);
        return by;
    }
C.M(Boolean)
    C.M(Boolean)
    L0000: movzx eax, dl
    L0003: test eax, eax
    L0005: setne al
    L0008: movzx eax, al
    L000b: ret

However, as noted in the comments, depending on the compiler settings and whether your are building for .NET Framework or not, you may get additional code added as well. Compiling the below code for .NET Framework on sharplab.io results in code with call commands which could end up being slower depending on your hit-miss rate.





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...