1. ホーム
  2. c#

[解決済み】GUIDが一意でないことの簡単な証明【終了しました

2022-03-26 11:23:21

質問

GUIDが一意でないことを簡単なテストプログラムで証明したいのですが、どうすればいいですか? 以下のコードが何時間も実行されることを期待しましたが、うまくいきません。どうしたら動くようになりますか?

BigInteger begin = new BigInteger((long)0);
BigInteger end = new BigInteger("340282366920938463463374607431768211456",10);  //2^128
for(begin; begin<end; begin++)
  Console.WriteLine(System.Guid.NewGuid().ToString());

C#を使っています。

どのように解決するのですか?

甲斐君、スレッドを使ってあなたの望むことを実現するプログラムを用意したんだ。このプログラムは次の条件でライセンスされています:あなたはそれを実行するCPUコアごとに1時間あたり0.0001ドルを私に支払う必要があります。料金は各月末に支払われます。私のペイパル口座の詳細については、お早めにご連絡ください。

using System;
using System.Collections.Generic;
using System.Linq;

namespace GuidCollisionDetector
{
    class Program
    {
        static void Main(string[] args)
        {
            //var reserveSomeRam = new byte[1024 * 1024 * 100];     // This indeed has no effect.

            Console.WriteLine("{0:u} - Building a bigHeapOGuids.", DateTime.Now);
            // Fill up memory with guids.
            var bigHeapOGuids = new HashSet<Guid>();
            try
            {
                do
                {
                    bigHeapOGuids.Add(Guid.NewGuid());
                } while (true);
            }
            catch (OutOfMemoryException)
            {
                // Release the ram we allocated up front.
                // Actually, these are pointless too.
                //GC.KeepAlive(reserveSomeRam);
                //GC.Collect();
            }
            Console.WriteLine("{0:u} - Built bigHeapOGuids, contains {1} of them.", DateTime.Now, bigHeapOGuids.LongCount());


            // Spool up some threads to keep checking if there's a match.
            // Keep running until the heat death of the universe.
            for (long k = 0; k < Int64.MaxValue; k++)
            {
                for (long j = 0; j < Int64.MaxValue; j++)
                {
                    Console.WriteLine("{0:u} - Looking for collisions with {1} thread(s)....", DateTime.Now, Environment.ProcessorCount);
                    System.Threading.Tasks.Parallel.For(0, Int32.MaxValue, (i) =>
                    {
                        if (bigHeapOGuids.Contains(Guid.NewGuid()))
                            throw new ApplicationException("Guids collided! Oh my gosh!");
                    }
                    );
                    Console.WriteLine("{0:u} - That was another {1} attempts without a collision.", DateTime.Now, ((long)Int32.MaxValue) * Environment.ProcessorCount);
                }
            }
            Console.WriteLine("Umm... why hasn't the universe ended yet?");
        }
    }
}

追記:Parallel extensions ライブラリを試してみたかったんです。簡単でしたね。

そして、OutOfMemoryExceptionを制御フローとして使うのは、間違っていると感じます。

EDIT

まあ、これはまだ票を集めているようです。というわけで、GC.KeepAlive()の問題を修正しました。そして、C# 4で動作するように変更しました。

そして、私のサポート条件を明確にするために:サポートは2010年2月28日にのみ可能です。タイムマシンを使って、その日だけサポート依頼をしてください。

EDIT 2 いつものように、GCはメモリ管理で私よりも良い仕事をしてくれます。自分でそれを行う以前の試みは失敗に終わりました。