将两个Int32组合到Int64中

pap*_*zzo 3 .net shift int64

使字典<Int64,byte>得到了很多使用.我的意思是在大数据负载中运行数天的循环.Int64来自两个Int32.该字节恰好是来自许多很长列表的那两个Int32之间的距离(计数).

我在这个循环中需要做的是

  • 生成密钥
  • 如果词典中不存在键,则插入键和值
  • 如果key确实存在且新值(byte)小于现有值,则将现有值替换为新值

现在我使用直接数学来生成密钥,我知道有更快的方法,但我无法弄明白.我把shift作为标签,因为我认为这是如何优化它,但我无法弄明白.

然后当循环完成时,我需要从Int64中提取两个Int32以将数据插入到数据库中.

谢谢

每个注释我使用的数学将两个Int32组合成一个Int64

        Int64 BigInt;
        Debug.WriteLine(Int32.MaxValue);
        Int32 IntA = 0;
        Int32 IntB = 1;
        BigInt = ((Int64)IntA * Int32.MaxValue) + IntB;
        Debug.WriteLine(BigInt.ToString());
        IntA = 1;
        IntB = 0;
        BigInt = ((Int64)IntA * Int32.MaxValue) + IntB;
        Debug.WriteLine(BigInt.ToString());
        IntA = 1;
        IntB = 1;
        BigInt = ((Int64)IntA * Int32.MaxValue) + IntB;
        Debug.WriteLine(BigInt.ToString());
Run Code Online (Sandbox Code Playgroud)

最好的密钥可能不是Int64.我所拥有的是两个Int32,它们共同形成一个键.和一个字节的值.我需要快速查找该复合键.字典很快但它不支持复合键,因此我创建了一个实际上是复合键的单个键.在SQL Int32A中,Int32B形成PK.

我不使用复合键的原因是我希望字典的查找速度和我的知识字典不支持复合键.这是生产代码.在SQL表中实际上有第三个键(Int32 sID,Int32 IntA,Int32 IntB).在这个解析器中,我一次只处理一个sID(并按顺序处理sID).我开始使用SQL的复合键查找(运行中数十亿).当我拉出IntA时,IntB输出到Dictionary以处理单个sID,然后在每个sID完成时加载到SQL我获得了100:1的性能提升.部分性能改进是插入,因为当我从字典插入时我可以按PK顺序插入.新的IntA和IntB不是按解析方式生成的,因此直接插入SQL会严重破坏索引,我需要在运行结束时重建索引.

Bas*_*Bas 11

如果要在Int32中来回转换为Int64,可以使用具有显式布局的结构:

//using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Explicit)]
struct Int64ToInt32
{
    [FieldOffset(0)]
    public Int64 Int64Value;
    [FieldOffset(0)]
    public Int32 LeftInt32;
    [FieldOffset(4)]
    public Int32 RightInt32;
}
Run Code Online (Sandbox Code Playgroud)

只需从字段中设置/获取值即可.


Jon*_*eet 8

听起来你只是想换班.我个人觉得在使用无符号类型而不是有符号类型时考虑位移更简单:

// Note: if you're in a checked context by default, you'll want to make this
// explicitly unchecked
uint u1 = (uint) int1;
uint u2 = (uint) int2;

ulong unsignedKey = (((ulong) u1) << 32) | u2;
long key = (long) unsignedKey;
Run Code Online (Sandbox Code Playgroud)

并扭转:

ulong unsignedKey = (long) key;
uint lowBits = (uint) (unsignedKey & 0xffffffffUL);
uint highBits = (uint) (unsignedKey >> 32);
int i1 = (int) highBits;
int i2 = (int) lowBits;
Run Code Online (Sandbox Code Playgroud)

您完全有可能不需要将所有这些转换都转换为无符号类型.这比我的理智更重要:)

请注意,您需要转换u1为a ulong以使移位在正确的空间中工作 - 将uint32 位移位无效.

请注意,这是一种组合两个32位整数以获得64位整数的方法.这绝不是唯一的办法.

(旁注:Bas的解决方案非常有效 - 我对这种方法总是有点不舒服,没有特别的原因.)