c# - C# 提高数组查找循环性能
问题描述
我有一个Datapoint[] file = new Datapoint[2592000]
数组。这个数组充满了时间戳和随机值。创建它们要花费我 2 秒。但在另一个函数中prepareData();
,我正在为另一个 Array 准备 240 个值TempBuffer
。在prepareData()
函数中,我正在搜索file
数组中的匹配值。如果我找不到任何时间戳并将值设置为 0,否则我将使用找到的值 + 相同的时间戳。
该函数如下所示:
public void prepareData()
{
stopWatch.Reset();
stopWatch.Start();
Int32 unixTimestamp = (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;
for (double i = unixTimestamp; unixTimestamp - 240 < i; i--)
{
bool exists = true;
if (exists != (Array.Exists(file, element => element.XValue == i)))
{
TempBuffer = TempBuffer.Skip(1).Concat(new DataPoint[] { new DataPoint(UnixTODateTime(i).ToOADate(), 0) }).ToArray();
}
else
{
DataPoint point = Array.Find(file, element => element.XValue == i);
TempBuffer = TempBuffer.Skip(1).Concat(new DataPoint[] { new DataPoint(UnixTODateTime(i).ToOADate(), point.YValues) }).ToArray();
}
}
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
}
现在问题在于file
(2'592'000) 中的数据量,该函数需要 40 秒!对于像 10'000 这样的较小金额,这不是问题,而且工作正常且快速。但是,一旦我将file
大小设置为我喜欢的 2'592'000 点,CPU 就会被推到 99% 的性能,并且该功能需要的时间太长了。
TempBuffer 样本值:
X = UnixTimeStamp 转换为 DateTime 和 DateTime 转换为 AODate
{X=43285.611087963, Y=23}
文件样本值:
X = Unixtimestamp
{X=1530698090, Y=24}
将 tempbuffer 值转换为 AODate 很重要,因为 tempbuffer 数组中的数据显示在 mschart 中。
有没有办法改进我的代码,让我有更好的性能?
解决方案
Array.Exists() 和 Array.Find() 是 O(N) 操作,您正在执行它们 x M (240) 次。
尝试 LINQ Join 代替:
DataPoint[] dataPoints; // your "file" variable
var seekedTimestamps = Enumerable.Range(0, 240).Select(i => unixTimestamp - i);
var matchingDataPoints = dataPoints.Join(seekedTimestamps, dp => dp.XValue, sts => sts, (dp, sts) => dp);
var missingTimestamps = seekedTimestamps.Except(matchingDataPoints.Select(mdp => mdp.XValue));
// do your logic with found and missing here
// ...
LINQ Join 使用散列(在选定的“键”上)并且接近 O(n)
或者,假设输入中的时间戳是唯一的,并且您计划对输入执行多个操作,请构造一个Dictionary<int (Timestamp), DataPoint>
(昂贵的),这将为您提供 O(1) 检索所需数据点:var dataPoint = dict[wantedTimestamp];
推荐阅读
- angular-routing - 每次激活组件的路由中的参数更改时如何激活组件
- javascript - nodejs - 包含带有加密文件数据的 iv
- java - 使用 JAVA 生成大于当前日期的随机日期
- html - 无法理解 css 的位置属性
- javascript - net::ERR_CACHE_MISS react-native-webview on Android 5
- javascript - 使用带有 RenderCell 的自动完成组件的 Material-UI 数据网格滞后和性能问题
- servlets - 传参数时404
- delphi - TIdTCPClient 连接池
- spring-boot - 在运行时创建和绑定一个独占和自动删除的rabbitmq队列,定义的到期时间失败
- excel - 工作表审核日志第 2 部分