我正在使用LinkedList,并在存储要更新的数据,对其执行计算和删除旧更新之间进行切换。 要执行此操作,我必须锁定读取和采样部分,但这会带来性能上的提升。 由于我不断添加和删除节点,因此我认为LinkedList是此任务的最佳数据结构(据我所知,为此使用列表将导致复制列表的多种动作) 据我所知,LinkedList没有线程安全的实现。 我正在大量数据上运行此代码,并且需要几个小时才能完成。 有什么办法可以加快速度吗?
编辑:我将节点添加到列表的末尾,并从列表的开头删除
private readonly ConcurrentQueue<Update> _UpdatesQueue = new ConcurrentQueue<Update>();
private volatile bool _AddingUpdates = false;
public void InsertUpdate(Update update)
{
_UpdatesQueue.Enqueue(update);
if (_AddingUpdates)
{
return;
}
lock (_updateQueueLock)
{
if (_AddingUpdates)
{
return;
}
_AddingUpdates = true;
}
Task.Factory.StartNew(() =>
{
lock (_updateQueueLock)
{
Update lastupdate = null;
while (_UpdatesQueue.TryDequeue(out update))
{
updateWindow.AddLast(update);
}
}
}).ContinueWith(x =>
{
_AddingUpdates = false;
});
}
private volatile bool _Sampling = false;
private readonly ConcurrentQueue<Tuple<Timestamp, Action<float>>> _RequestsQueue = new ConcurrentQueue<Tuple<Timestamp, Action<float>>>();
public void GetFeatureAtTime(Timestamp time, Action<float> valueCallback)
{
_RequestsQueue.Enqueue(new Tuple<Timestamp, Action<float>>(time, valueCallback));
if (_Sampling)
{
return;
}
lock (_updateQueueLock)
{
if (_Sampling)
{
return;
}
_Sampling = true;
}
Task.Factory.StartNew(() =>
{
lock (_updateQueueLock)
{
Timestamp lastTime = null;
while (_RequestsQueue.TryPeek(out var request))
{
GetFeatureAtTimeInternal(request.Item1, request.Item2, out var haveEnoughData);
if (haveEnoughData)
{
_RequestsQueue.TryDequeue(out _);
}
else
{
break;
}
}
}
}).ContinueWith(x => _Sampling = false);
}
根据我在VS中的并发可视化工具中看到的信息,有76%的cpu用于同步化。 而且,与插入相比,采样有时可能是一个笨拙的动作。