C# 列表的性能问题
我的数据库中有10亿条记录,需要用20个值随机更新所有行。C# 列表的性能问题,c#,performance,list,for-loop,C#,Performance,List,For Loop,我的数据库中有10亿条记录,需要用20个值随机更新所有行。 因此,对于每5000万条随机记录,需要更新1个值。 所以,我想生成一个包含10亿个数字的列表,从列表中随机选择5000万条记录,然后从列表中删除5000万条记录,以此类推 我的代码: 列表创建: List<long> LstMainList = new List<long>(); for (int i = 1; i <= 999999999; i++) { LstMainList.Add(i); }
因此,对于每5000万条随机记录,需要更新1个值。
所以,我想生成一个包含10亿个数字的列表,从列表中随机选择5000万条记录,然后从列表中删除5000万条记录,以此类推 我的代码: 列表创建:
List<long> LstMainList = new List<long>();
for (int i = 1; i <= 999999999; i++)
{
LstMainList.Add(i);
}
List LstMainList=newlist();
对于(int i=1;i批量复制列表(复制列表,“计划表1”);
previousThread.Start();
表1.Clear();
}
}
现在,我的问题是:在LstMainList.RemoveAt(lstinex)的行中代码>,从主列表中删除索引需要很长时间,因为它包含10亿条记录
有没有一种方法可以简单地从列表中删除记录?或者用其他方法来简化这件事 首先-对ID使用数组而不是列表(尤其是在没有初始化容量的情况下)
对于无序ID,您不需要修改ID列表。在任意位置移除物品是非常昂贵的操作。若删除位置0处的项,则整个列表应复制到新数组中。现在您可以迭代ids数组
或者,您可以使用创建批次TableData并将其批量处理:
int size = 100000;
foreach(var batch in ids.Batch(size, id => new TableData { MESSAGE_ID = id }))
{
var copyList = batch.ToList();
// ...
}
更新:因此您需要不同大小的批,您可以使用以下扩展方法从数组中获取项目范围:
public static IEnumerable<T> GetRange<T>(
this T[] array, int startIndex, int count)
{
for (int i = startIndex; i < startIndex + count; i++)
yield return array[i];
}
当然,更有效的方法是迭代ids数组,并使用预初始化功能将项目添加到列表中:
int size = 5000;
int startIndex = 20000;
List<TableData> copyList = new List<TableData>(size);
for (int i = startIndex; i < startIndex + size; i++)
copyList.Add(new TableData { MESSAGE_ID = ids[i] });
int size=5000;
int startIndex=20000;
列表复制列表=新列表(大小);
对于(inti=startIndex;i
更进一步,我会将TableData对象创建移动到执行大容量复制的线程。并且刚刚传递了它应该使用的ID序列。首先-对ID使用数组而不是列表(特别是在没有初始化容量的情况下)
对于无序ID,您不需要修改ID列表。在任意位置移除物品是非常昂贵的操作。若删除位置0处的项,则整个列表应复制到新数组中。现在您可以迭代ids数组
或者,您可以使用创建批次TableData并将其批量处理:
int size = 100000;
foreach(var batch in ids.Batch(size, id => new TableData { MESSAGE_ID = id }))
{
var copyList = batch.ToList();
// ...
}
更新:因此您需要不同大小的批,您可以使用以下扩展方法从数组中获取项目范围:
public static IEnumerable<T> GetRange<T>(
this T[] array, int startIndex, int count)
{
for (int i = startIndex; i < startIndex + count; i++)
yield return array[i];
}
当然,更有效的方法是迭代ids数组,并使用预初始化功能将项目添加到列表中:
int size = 5000;
int startIndex = 20000;
List<TableData> copyList = new List<TableData>(size);
for (int i = startIndex; i < startIndex + size; i++)
copyList.Add(new TableData { MESSAGE_ID = ids[i] });
int size=5000;
int startIndex=20000;
列表复制列表=新列表(大小);
对于(inti=startIndex;i
更进一步,我会将TableData对象创建移动到执行大容量复制的线程。刚刚传递了它应该使用的ID序列。首先,这里是
第二,如果没有用,请继续阅读
如果您知道要随机选择的项目数,以及要随机选择的序列中的项目数,则存在O(N)解决方案
在下面的示例中,方法RandomlySelectedItems()
提供了一系列随机选择的项目
这是密码。(重申,只有在您事先知道要从中选择的项目数量时,才能使用此选项):
使用系统;
使用System.Collections.Generic;
使用System.Linq;
名称空间演示
{
内部静态类程序
{
静态void Main(字符串[]参数)
{
int numberOfValuesToSelectFrom=10000000;
int numberOfValuesToSelect=20;
var valuesToSelectFrom=可枚举的范围(1,numberOfValuesToSelectFrom);
var selectedValues=RandomlySelectedItems
(
值从中选择,
NumberOfValues可选择,
要从中选择的NumberOfValues,
新随机数()
);
foreach(选定值中的int值)
控制台写入线(值);
}
///从序列中随机选择项目。
///序列中项目的类型。
///从中随机选择项目的顺序。
///从序列中随机选择的项目数。
///顺序中要随机选择的项目数。
///要使用的随机数生成器。
///一系列随机选择的项目。
///这是一个O(N)算法(N是序列长度)。
公共静态IEnumerable RandomlySelectedItems(IEnumerable序列、int计数、int序列长度、随机rng)
{
if(sequence==null)
抛出新的ArgumentNullException(“序列”);
如果(计数<0 | |计数>序列长度)
抛出新ArgumentOutOfRangeException(“count”,count,“count必须介于0和sequenceLength之间”);
如果(rng==null)
抛出新的ArgumentNullException(“rng”);
int available=sequenceLength;
剩余整数=计数;
var iterator=sequence.GetEnumerator();
用于(int电流=0;电流<序列长度;++电流)
{
iterator.MoveNext();
如果(rng.NextDouble()<剩余/(双倍)可用)
{
产生返回迭代器.Current;
--剩余的;
}
--可用的;
}
}
}
}
首先,这里是
第二,如果没有用,请继续阅读
如果您知道要随机选择的项目数,以及要随机选择的序列中的项目数,则存在O(N)解决方案
在下面的示例中,方法RandomlySelectedItems()
提供了一系列随机选择的项目
这是密码。(致房地产投资信托基金)
int size = 5000;
int startIndex = 20000;
List<TableData> copyList = new List<TableData>(size);
for (int i = startIndex; i < startIndex + size; i++)
copyList.Add(new TableData { MESSAGE_ID = ids[i] });
using System;
using System.Collections.Generic;
using System.Linq;
namespace Demo
{
internal static class Program
{
static void Main(string[] args)
{
int numberOfValuesToSelectFrom = 10000000;
int numberOfValuesToSelect = 20;
var valuesToSelectFrom = Enumerable.Range(1, numberOfValuesToSelectFrom);
var selectedValues = RandomlySelectedItems
(
valuesToSelectFrom,
numberOfValuesToSelect,
numberOfValuesToSelectFrom,
new Random()
);
foreach (int value in selectedValues)
Console.WriteLine(value);
}
/// <summary>Randomly selects items from a sequence.</summary>
/// <typeparam name="T">The type of the items in the sequence.</typeparam>
/// <param name="sequence">The sequence from which to randomly select items.</param>
/// <param name="count">The number of items to randomly select from the sequence.</param>
/// <param name="sequenceLength">The number of items in the sequence among which to randomly select.</param>
/// <param name="rng">The random number generator to use.</param>
/// <returns>A sequence of randomly selected items.</returns>
/// <remarks>This is an O(N) algorithm (N is the sequence length).</remarks>
public static IEnumerable<T> RandomlySelectedItems<T>(IEnumerable<T> sequence, int count, int sequenceLength, Random rng)
{
if (sequence == null)
throw new ArgumentNullException("sequence");
if (count < 0 || count > sequenceLength)
throw new ArgumentOutOfRangeException("count", count, "count must be between 0 and sequenceLength");
if (rng == null)
throw new ArgumentNullException("rng");
int available = sequenceLength;
int remaining = count;
var iterator = sequence.GetEnumerator();
for (int current = 0; current < sequenceLength; ++current)
{
iterator.MoveNext();
if (rng.NextDouble() < remaining/(double)available)
{
yield return iterator.Current;
--remaining;
}
--available;
}
}
}
}
private static IEnumerable<int> GenerateSequence()
{
const int max = 1000000000;
const long a = 11268619, b = 4064861;
for(int i = 0; i < max; i++)
{
int c = (int)((a * i + b) % max);
yield return c;
}
}