List<int> 上更快的随机生成器(指定种子)
faster random generator on List<int> (specified seeds)
首先是关于性能的问题:我可以使随机生成速度更快吗?鉴于:
我正在实施一个 .Shuffle() 扩展方法(在 SO 中找到)
尽管使用得当(即几乎没有时间再生)
它变得非常慢,因为我的需要是在 for 循环中重复生成
每个种子集超过 1k 次。
假设 'banks' 是
List<int> seedLst1 = new List<int>(){2, 4, 6, 8, 10.....}
List<int> seedLst2 = new List<int>(){10, 15, 20, 11, 22, 33.....}
所以我将它们作为参数调用(在容器内)
List<List<int>> allSeedSetsLst
//randsPerSet - how many random items in each resultset
//count - total iteration on each of the sorces
List<List<int>> getRandRes(List<List<int>> SeedsBank, int count, int randsperSet)
{
List<List<int>> RetGuessList = new List<List<int>>();
foreach (var CurSeedLst in SeedsBank)
{
int randomIntrval = 55;
List<int> curRandSet;
for (i=0; i < count; i++)
{
curRandSet = new List<int>();
System.Threading.Thread.Sleep(randomInterval * 15);
curRandSet = CurSeedLst.Shuffle().Take(randsperSet);
randomInterval = curRandSet.Last();
RetGuessList.Add(curRandSet);
}
}
return RetGuessList;
}
随机码
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source)
{
return source.Shuffle(new Random());
}
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source, Random rng)
{
if (source == null) throw new ArgumentNullException("source");
if (rng == null) throw new ArgumentNullException("rng");
return source.ShuffleIterator(rng);
}
private static IEnumerable<T> ShuffleIterator<T>(this IEnumerable<T> source, Random rng)
{
List<T> buffer = source.ToList();
for (int i = 0; i < buffer.Count; i++)
{
int j = rng.Next(i, buffer.Count);
yield return buffer[j];
buffer[j] = buffer[i];
}
}
不要使用 Thread.Sleep
来防止随机重复,您已经有一个扩展,它接受 Random
使用单个实例并使用它,实际上复制模式,有一个接受 Random
的重载和一个创建新的重载。
List<List<int>> getRandRes(List<List<int>> SeedsBank, int count, int randsperSet)
{
return getRandRes(SeedsBank, count, randsperSet, new Random());
}
List<List<int>> getRandRes(List<List<int>> SeedsBank, int count, int randsperSet, Random rand)
{
List<List<int>> RetGuessList = new List<List<int>>();
foreach (var CurSeedLst in SeedsBank)
{
for (i=0; i < count; i++)
{
var curRandSet = CurSeedLst.Shuffle(rand).Take(randsperSet).ToList();
RetGuessList.Add(curRandSet);
}
}
return RetGuessList;
}
现在对 Shuffle
的每次调用都将使用相同的 Random
对象,而不是需要创建一个新对象,这消除了对随机 Thread.Sleep
调用的需要。
P.S.: 你没有遵循 C# 的标准 capitalization conventions。正确的方法是(加上其他一些调整)
List<List<int>> GetRandRes(List<List<int>> seedsBank, int count, int randsperSet, Random rand)
{
var retGuessList = new List<List<int>>(seedsBank.Count * count);
foreach (var curSeedLst in seedsBank)
{
for (i=0; i < count; i++)
{
var curRandSet = curSeedLst.Shuffle(rand).Take(randsperSet).ToList();
retGuessList.Add(curRandSet);
}
}
return retGuessList;
}
首先是关于性能的问题:我可以使随机生成速度更快吗?鉴于: 我正在实施一个 .Shuffle() 扩展方法(在 SO 中找到) 尽管使用得当(即几乎没有时间再生) 它变得非常慢,因为我的需要是在 for 循环中重复生成 每个种子集超过 1k 次。
假设 'banks' 是
List<int> seedLst1 = new List<int>(){2, 4, 6, 8, 10.....}
List<int> seedLst2 = new List<int>(){10, 15, 20, 11, 22, 33.....}
所以我将它们作为参数调用(在容器内)
List<List<int>> allSeedSetsLst
//randsPerSet - how many random items in each resultset
//count - total iteration on each of the sorces
List<List<int>> getRandRes(List<List<int>> SeedsBank, int count, int randsperSet)
{
List<List<int>> RetGuessList = new List<List<int>>();
foreach (var CurSeedLst in SeedsBank)
{
int randomIntrval = 55;
List<int> curRandSet;
for (i=0; i < count; i++)
{
curRandSet = new List<int>();
System.Threading.Thread.Sleep(randomInterval * 15);
curRandSet = CurSeedLst.Shuffle().Take(randsperSet);
randomInterval = curRandSet.Last();
RetGuessList.Add(curRandSet);
}
}
return RetGuessList;
}
随机码
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source)
{
return source.Shuffle(new Random());
}
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source, Random rng)
{
if (source == null) throw new ArgumentNullException("source");
if (rng == null) throw new ArgumentNullException("rng");
return source.ShuffleIterator(rng);
}
private static IEnumerable<T> ShuffleIterator<T>(this IEnumerable<T> source, Random rng)
{
List<T> buffer = source.ToList();
for (int i = 0; i < buffer.Count; i++)
{
int j = rng.Next(i, buffer.Count);
yield return buffer[j];
buffer[j] = buffer[i];
}
}
不要使用 Thread.Sleep
来防止随机重复,您已经有一个扩展,它接受 Random
使用单个实例并使用它,实际上复制模式,有一个接受 Random
的重载和一个创建新的重载。
List<List<int>> getRandRes(List<List<int>> SeedsBank, int count, int randsperSet)
{
return getRandRes(SeedsBank, count, randsperSet, new Random());
}
List<List<int>> getRandRes(List<List<int>> SeedsBank, int count, int randsperSet, Random rand)
{
List<List<int>> RetGuessList = new List<List<int>>();
foreach (var CurSeedLst in SeedsBank)
{
for (i=0; i < count; i++)
{
var curRandSet = CurSeedLst.Shuffle(rand).Take(randsperSet).ToList();
RetGuessList.Add(curRandSet);
}
}
return RetGuessList;
}
现在对 Shuffle
的每次调用都将使用相同的 Random
对象,而不是需要创建一个新对象,这消除了对随机 Thread.Sleep
调用的需要。
P.S.: 你没有遵循 C# 的标准 capitalization conventions。正确的方法是(加上其他一些调整)
List<List<int>> GetRandRes(List<List<int>> seedsBank, int count, int randsperSet, Random rand)
{
var retGuessList = new List<List<int>>(seedsBank.Count * count);
foreach (var curSeedLst in seedsBank)
{
for (i=0; i < count; i++)
{
var curRandSet = curSeedLst.Shuffle(rand).Take(randsperSet).ToList();
retGuessList.Add(curRandSet);
}
}
return retGuessList;
}