List <int>(指定种子)上更快的随机生成器

时间:2015-08-22 16:50:31

标签: c# performance random parallel-processing

首先问题是关于性能:我可以更快地进行随机生成吗?鉴于: 我正在实现.Shuffle()扩展方法(在SO中找到) 虽然使用得当(即没有时间再生) 它变得非常慢,因为我的需求是在for循环中重复genaration 每个种子集超过1k次。

说“银行”是

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];
    }
}

1 个答案:

答案 0 :(得分:3)

不要使用Thread.Sleep来阻止Random重复,你已经有一个扩展,它接受Random使用单个实例并使用它而实际上复制模式,有一个重载它接收Random而另一个产生新的。{/ p>

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;
}
相关问题