Performance issue with generation of random unique numbers

前端 未结 10 528
星月不相逢
星月不相逢 2021-01-17 13:47

I have a situation where by I need to create tens of thousands of unique numbers. However these numbers must be 9 digits and cannot contain any 0\'s. My current approach is

相关标签:
10条回答
  • 2021-01-17 14:33

    Looking at the solutions already posted, mine seems fairly basic. But, it works, and generates 1million values in approximate 1s (10 million in 11s).

    public static void generateIdentifiers(int quantity)
    {
        HashSet<int> uniqueIdentifiers = new HashSet<int>();
    
        while (uniqueIdentifiers.Count < quantity)
        {
            int value = random.Next(111111111, 999999999);
            if (!value.ToString().Contains('0') && !uniqueIdentifiers.Contains(value))
                uniqueIdentifiers.Add(value);
        }
    }
    
    0 讨论(0)
  • 2021-01-17 14:35

    As others have mentioned, use a HashSet<T> instead of a List<T>.
    Furthermore, using StringBuilder instead of simple string operations will gain you another 25%. If you can use numbers instead of strings, you win, because it only takes a third or fourth of the time.

    var quantity = 400000;
    var uniqueIdentifiers = new HashSet<int>();
    while (uniqueIdentifiers.Count < quantity)
    {
        int i=0;
        i = i*10 + random.Next(1,10);
        i = i*10 + random.Next(1,10);
        i = i*10 + random.Next(1,10);
        i = i*10 + random.Next(1,10);
        i = i*10 + random.Next(1,10);
        i = i*10 + random.Next(1,10);
        i = i*10 + random.Next(1,10);
        i = i*10 + random.Next(1,10);
        i = i*10 + random.Next(1,10);
        uniqueIdentifiers.Add(i);
    }
    

    It takes about 270 ms on my machine for 400,000 numbers and about 700 for 1,000,000. And this even without any parallelism. Because of the use of a HashSet<T> instead of a List<T>, this algorithm runs in O(n), i.e. the duration will grow linear. 10,000,000 values therefore take about 7 seconds.

    0 讨论(0)
  • 2021-01-17 14:38

    Meybe this will bee faster:

            //we can generate first number wich in 9 base system will be between 88888888 - 888888888 
            //we can't start from zero becouse it will couse the great amount of 1 digit at begining
    
            int randNumber = random.Next((int)Math.Pow(9, 8) - 1, (int)Math.Pow(9, 9));
    
    
            //no we change our number to 9 base, but we add 1 to each digit in our number
            StringBuilder builder = new StringBuilder();
    
            for (int i=(int)Math.Pow(9,8); i>0;i= i/9)
            {
                builder.Append(randNumber / i +1);
                randNumber = randNumber % i;
            }
    
            id = builder.ToString();
    
    0 讨论(0)
  • 2021-01-17 14:38

    I think first thing would be to use StringBuilder, instead of concatenation - you'll be pleasantly surprised. Antoher thing - use a more efficient data structure, for example HashSet<> or HashTable.

    If you could drop the quite odd requirement not to have zero's - then you could of course use just one random operation, and then format your resulting number the way you want.

    0 讨论(0)
提交回复
热议问题