HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpModerate

Tuple<int, int> replacement

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
tupleintreplacement

Problem

I use the following structure in a web service where performance is critical. It is used for making joins between domain data objects, the key is made of two integers. The idea is to fit the two 32 bits integer in a long (64 bits).

Before using that structure, I used Tuple which was really slower.

Is there any additional optimization to be made? (e.g.: addtional override, unneeded cast etc...)

public struct CombinedKey : IEquatable
{
   private readonly long value;

   public CombinedKey(int item1, int item2)
   {
        unchecked
        {
            value = (long)item1 > 32);
    }

    public bool Equals(CombinedKey other)
    {
        return this.value == other.value;
    }

    public int Item1
    {
        get
        {
            return (int)(this.value >> 32);
        }
    }

    public int Item2
    {
        get
        {
            return (int)(this.value & 0xffffffff);
        }
    }
}

Solution

You could use explicit layout of the structure to omit values calculation.

It can act similar to the union in C/C++:

[StructLayout(LayoutKind.Explicit)]
public struct CombinedKey : IEquatable
{
    [FieldOffset(0)]
    private readonly long value;
    [FieldOffset(0)]
    public readonly int Item1;
    [FieldOffset(sizeof(int))]
    public readonly int Item2;

    public CombinedKey(int item1, int item2)
    {
        value = 0;  // We need to init all the fields
        Item1 = item1;
        Item2 = item2;
    }

    public bool Equals(CombinedKey other)
    {
        return value == other.value;
    }

    public override int GetHashCode()
    {
        return Item1 ^ Item2;
    }
}


You could also wrap readonly fields into get-only properties.

Additional link: [StructLayout attribute magic][2]

Code Snippets

[StructLayout(LayoutKind.Explicit)]
public struct CombinedKey : IEquatable<CombinedKey>
{
    [FieldOffset(0)]
    private readonly long value;
    [FieldOffset(0)]
    public readonly int Item1;
    [FieldOffset(sizeof(int))]
    public readonly int Item2;

    public CombinedKey(int item1, int item2)
    {
        value = 0;  // We need to init all the fields
        Item1 = item1;
        Item2 = item2;
    }

    public bool Equals(CombinedKey other)
    {
        return value == other.value;
    }

    public override int GetHashCode()
    {
        return Item1 ^ Item2;
    }
}

Context

StackExchange Code Review Q#104412, answer score: 16

Revisions (0)

No revisions yet.