5

IDに依存しないデータ型(基本的には、すべての可能なIDを1つの列に含めるためにの「グローバルに一意」の部分を利用した古いコード)で使用するために、新しく移行intされたID値を型に格納するという従来の要件があります。 /分野)。guidguid

guidこの要件のために、人間が読める形式でエンティティの整数IDを埋め込むという後続の要件がありました。これは重要であり、現在、バイト値に対して直接作業することを妨げている原因です。

現在、私は次のものを持っています:

    public static byte[] IntAsHexBytes(int value)
    {
        return BitConverter.GetBytes(Convert.ToInt64(value.ToString(), 16));
    }

    public static Guid EmbedInteger(int id)
    {
        var ib = IntAsHexBytes(id);

        return new Guid(new byte[]
            {
                0,0,0,0,0,0,1,64,ib[7],ib[6],ib[5],ib[4],ib[3],ib[2],ib[1],ib[0]
            });
    }

の視覚的表現をint16進値( )として扱い、それを(value.ToString())に変換、特定の構造でを作成するために、からバイトをフラット化して取得します。longConvert.ToInt64(value.ToString(), 16)longbyte[]guid

したがって、42が与えられたint場合、42を16進数として扱い、それを1に変換するlong、66が得られ、66のバイトに変換すると、次のようになりguidます。

"00000000-0000-4001-0000-000000000042"

そして、intのは379932126与える:

"00000000-0000-4001-0000-000379932126"

したがって、最終結果は、整数をguid最後の12桁に配置して、視覚的に整数42のように見えるようにします(基になる整数値が66であったとしても)。

これは、コンストラクターにフィードするために連結を使用して文字列を作成するよりも約30%〜40%高速new Guid(string)ですが、そもそも文字列を使用する必要がないという解決策が欠けていると感じています。

関係する実際のタイミングは非常に小さいので、パフォーマンスの向上として、おそらく努力を正当化することはできません。

これは純粋に、この問題に取り組むより速い方法があるかどうかを確認するための私自身の好奇心のためです。私は長年のSOユーザーであるため、ここに投稿しましたが、これがコードレビューのような質問であるかどうかについては悩んでいます。コードに対して直接何も求めていませんが、それは私が何を示しているかを示しています。出力として欲しい。

提供される整数範囲は0からint.MaxValue。です。

更新:完全を期すために、これは私たちが現在持っているものであり、私がテストしているものです:

string s = string.Format("00000000-0000-4001-0000-{0:D12}", id);
return new Guid(s);

上記の他のコードは、これよりも約30%高速です。

4

2 に答える 2

1

これがあなたが望むことをするだろうと思います。コードよりも効率的かどうかはわかりませんが、少なくとも少し短いです。:)

public static Guid EmbedInteger(int id)
{
    string guid = string.Format("00000000-0000-4001-0000-{0,12:D12}", id);
    return new Guid(guid);
}

これは、数値形式12:D12を使用して機能します。これにより、入力番号は、先行ゼロを含むフィールド幅12の10進数として形式化されます。

于 2012-07-31T11:13:09.480 に答える
1

さて、これは文字列を完全に回避する別のバージョンです。うまくいけば、これはもっと良いかもしれません。:)

public static Guid EmbedInteger(int id)
{
    byte[] bytes = new byte[8];
    int i = 0;

    while (id > 0)
    {
        int remainder = id%100;
        bytes[i++] = (byte)(16*(remainder/10) + remainder%10);
        id /= 100;
    }

    return new Guid(0, 0, 0x4001, bytes[7], bytes[6], bytes[5], bytes[4], bytes[3], bytes[2], bytes[1], bytes[0]);
}

Adam Houldsworth:更新:このコードは展開することもできます:

int remainder = id % 100;
bytes[0] = (byte)(16 * (remainder / 10) + remainder % 10);
id /= 100;
if (id == 0) return;
remainder = id % 100;
bytes[1] = (byte)(16 * (remainder / 10) + remainder % 10);
id /= 100;
if (id == 0) return;
remainder = id % 100;
bytes[2] = (byte)(16 * (remainder / 10) + remainder % 10);
id /= 100;
if (id == 0) return;
remainder = id % 100;
bytes[3] = (byte)(16 * (remainder / 10) + remainder % 10);
id /= 100;
if (id == 0) return;
remainder = id % 100;
bytes[4] = (byte)(16 * (remainder / 10) + remainder % 10);
于 2012-07-31T11:29:34.557 に答える