C# 生成随机16位字符串

C# 生成随机16位字符串,c#,C#,创建随机16位字符串的更好方法是什么?我已经使用了这段代码,你能推荐一种更有效或更优雅的方法吗 static string Random16DigitString() { var rand = new Random(); return $"{rand.Next(100000000).ToString().PadLeft(8, '0')}{rand.Next(100000000).ToString().PadLeft(8, '0')}"; } PS:我这样做的原因是创建一个0.0

创建随机16位字符串的更好方法是什么?我已经使用了这段代码,你能推荐一种更有效或更优雅的方法吗

static string Random16DigitString() {
    var rand = new Random();
    return $"{rand.Next(100000000).ToString().PadLeft(8, '0')}{rand.Next(100000000).ToString().PadLeft(8, '0')}";
}
PS:我这样做的原因是创建一个0.0000000000000000格式的字符串,因此我将按以下方式使用它:

var myString = "0." + Random16DigitString();

您的解决方案依赖于字符串操作,这将减慢它的速度

尝试:

这将更快,因为它不依赖于串接或插值等字符串操作。它只是将随机字符插入字符数组,然后将该数组转换为字符串。在我的机器上执行1亿次解决方案大约需要47秒,我的代码大约需要27秒才能产生相同的结果

r、 Next10+48可以在上面的代码中工作,但实际上有点慢。r、 Next48,57更慢


您的代码也可以更简单${rand.next10000000:D8}{rand.next10000000:D8}也会这样做。执行的时间差不多相同。

以下是我最后使用的代码:

    static readonly Random rnd = new Random();
    static string Q() {
        // https://stackoverflow.com/questions/767999/random-number-generator-only-generating-one-random-number/768001#768001
        // It was decided to use a lock instead of [ThreadStatic] because this api object is designed to be used by many threads simultaneously.
        lock (rnd) {
            // Get a string representing a positive number greater than 0 and less than 1 with exactly 16 decimal places.
            // Original implementation
            //return $"0.{rnd.Next(100000000).ToString().PadLeft(8, '0')}{rnd.Next(100000000).ToString().PadLeft(8, '0')}";
            // This works but is slow
            //return rnd.NextDouble().ToString("F16");
            // Found a better faster way: https://stackoverflow.com/questions/48455624/generate-random-16-digit-string/48457354#48457354
            var chars = new char[18];
            chars[0] = '0';
            chars[1] = '.';
            for (var i = 2; i < 18; i++)
                chars[i] = (char)(rnd.NextDouble() * 10 + 48);
            return new string(chars);
        }
    }
以下是我使用的测试,感谢吉姆·伯格的回答

using System;
using System.Diagnostics;
using System.Text;

namespace NetCoreApp1 {
    class Program {
        static void Main(string[] args) {

            var sync = new object();
            var rnd = new Random();

            Time("method1", () => {
                var value = $"{rnd.Next(100000000).ToString().PadLeft(8, '0')}{rnd.Next(100000000).ToString().PadLeft(8, '0')}";
            });

            Time("method2", () => {
                var value = $"{rnd.Next(100000000):D8}{rnd.Next(100000000):D8}";
            });

            Time("next double", () => {
                var value = rnd.NextDouble().ToString("F16"); // turns out surprisingly slow, even slower than the first two
            });

            Time("method3", () => {
                var v = new char[16];
                for (var j = 0; j < 16; j++)
                    v[j] = (char)(rnd.NextDouble() * 10 + 48); // fastest
                var value = new string(v);
            });

            Time("method3 with lock", () => {
                lock (sync) {
                    var v = new char[16];
                    for (var j = 0; j < 16; j++)
                        v[j] = (char)(rnd.NextDouble() * 10 + 48); // a tiny bit slower with the lock
                    var value = new string(v);
                }
            });

            Time("method4", () => {
                var sb = new StringBuilder(16);
                for (var j = 0; j < 16; j++)
                    sb.Append((char)(rnd.NextDouble() * 10 + 48)); // slower than method 3
                var value = sb.ToString();
            });

            Console.WriteLine("Press Enter to exit.");
            Console.ReadLine();
        }

        static void Time(string testName, Action action) {
            var sw = Stopwatch.StartNew();
            for (var i = 0; i < 10000000; i++)
                action();
            sw.Stop();
            Console.WriteLine($"{testName}: {sw.ElapsedMilliseconds}ms");
        }

    }
}

你在用这些字符串做什么?首先,你不应该在每次调用中创建一个新的Random实例。将其缓存在ThreadStatic中,或者在其周围有一个带锁的实例。@MarcinJuraszek,我想知道-你有关于该主题的更多信息的链接吗?@jdpenix,我已经更新了这个问题,以显示我正在对该主题做什么strings@bboyle1234看见
using System;
using System.Diagnostics;
using System.Text;

namespace NetCoreApp1 {
    class Program {
        static void Main(string[] args) {

            var sync = new object();
            var rnd = new Random();

            Time("method1", () => {
                var value = $"{rnd.Next(100000000).ToString().PadLeft(8, '0')}{rnd.Next(100000000).ToString().PadLeft(8, '0')}";
            });

            Time("method2", () => {
                var value = $"{rnd.Next(100000000):D8}{rnd.Next(100000000):D8}";
            });

            Time("next double", () => {
                var value = rnd.NextDouble().ToString("F16"); // turns out surprisingly slow, even slower than the first two
            });

            Time("method3", () => {
                var v = new char[16];
                for (var j = 0; j < 16; j++)
                    v[j] = (char)(rnd.NextDouble() * 10 + 48); // fastest
                var value = new string(v);
            });

            Time("method3 with lock", () => {
                lock (sync) {
                    var v = new char[16];
                    for (var j = 0; j < 16; j++)
                        v[j] = (char)(rnd.NextDouble() * 10 + 48); // a tiny bit slower with the lock
                    var value = new string(v);
                }
            });

            Time("method4", () => {
                var sb = new StringBuilder(16);
                for (var j = 0; j < 16; j++)
                    sb.Append((char)(rnd.NextDouble() * 10 + 48)); // slower than method 3
                var value = sb.ToString();
            });

            Console.WriteLine("Press Enter to exit.");
            Console.ReadLine();
        }

        static void Time(string testName, Action action) {
            var sw = Stopwatch.StartNew();
            for (var i = 0; i < 10000000; i++)
                action();
            sw.Stop();
            Console.WriteLine($"{testName}: {sw.ElapsedMilliseconds}ms");
        }

    }
}