这是我第一次发帖…
请考虑我是一个业余爱好程序员.
症状:
我的目标是提高代码的性能.
该程序仅使用65%的CPU和500Mb内存.还有另外800Mb的可用物理内存可用于该程序,大约30%的CPU空闲运行.我不知道在哪里可以成为进一步利用资源和提高代码性能的瓶颈.
背景:
我写了一个批量测试财务算法的程序.这个算法有很多参数,我试图找到最好的参数组合.为此,我运行它以获得所有可能的参数组合.
该算法具有数据序列的输入.它遍历数据系列并产生结果.
为此,我将算法的代码插入到Parallel.Foreach循环中,该循环对每个参数组合运行一次.优化的关键代码是循环.
由于代码很长,我发布了主干:
...
class candle : IComparable<candle> //Data element to represent a candle and all chart data
{
public double open;
public double high;
...40 more
}
class param : IComparable<param>
{
public int par1;
public int par2;
public int par3;
... a few more
}
//Running program
{
List<candle> sourceCandleList = new List<candle>();
List<param> paramList = new List<param>(1000000);
// Code to populate sourceCandleList and paramList in here
}
// EDIT: Start parallel processing
Parallel.ForEach(paramList,
p =>
{
List<candle> CandleList = new List<candle>(sourceCandleList.Count);
foreach (var cndl in sourceCandleList)
{
candle c = new candle();
c.open = cndl.open;
c.high = cndl.high;
...
//Run calculations and populate fields in CandleList
}
//Evaluate results
}
该参数列表有大约140,000个元素. sourceCandleList有大约2.000个元素.这意味着我不断创建每个包含2000个项目的列表,然后在处理后删除列表.我在运行代码时可以看到GC每秒清理大约200Mb内存.目前Parallel.ForEach的1个循环需要80ms.该程序不会将任何数据写入磁盘,只能将最少的数据写入控制台.
也许阻止GC工作的一种方法是将CandleList保存在内存中,然后在下一个循环运行时覆盖它.为此,我需要为每个线程定义一个静态列表,但我不确定它是如何可能的.也许只是创建一堆列表,然后尝试在新线程启动时使用TryEnter捕获一个免费的列表?
编辑
我没有明确说明程序首先生成2个列表:sourceCandleList和paramList.然后,一旦完成,这些永远不会改变.在完全填充这两个列表之后,程序开始测试算法:sourceCandleList是输入,paramList中的一个记录是要应用的参数集.问题是程序每次都定义一个新的CandleList.所以我需要这样的东西:
ConcurrentQueue<List<candle>> ListOfCanldes = new ConcurrentQueue<List<candle>>();
但是我无法弄清楚正确的语法.
问题:
为什么CPU没有充分利用内存?我是否达到内存的最大读/写速度!?
我怎么能避免GC减慢程序?
我怎么能看到因为GC我实际上失去了多少时间?
我怎样才能提高性能?
最佳答案 为什么CPU没有充分利用内存?我是否达到内存的最大读/写速度!?
>信息不足以说明问题.但是使用Parallel.ForEach将限制您使用的线程数.可能不是使用列表,而是使用ConcurrentQueue或ConcurrentStack.
我会做这样的事情来更快地处理它们:
class Program
{
static ConcurrentQueue<candle> sourceCandleList = new ConcurrentQueue<candle>();
static ConcurrentBag<param> paramList = new ConcurrentBag<param>();
static void Main(string[] args)
{
var threads = new List<Thread>();
var numberOfThreads = 10;
for (int i = 0; i < numberOfThreads; i++)
{
threads.Add(new Thread(Run));
}
threads.ForEach(i => i.Start());
}
static void Run()
{
candle item;
while (sourceCandleList.TryDequeue(out item))
{
//do you processing here
}
}
}
我怎么能避免GC减慢程序? :不要担心GC.
我怎么能看到因为GC我实际上失去了多少时间?
您可以使用VS 2015的分析 – 或者下载Ant Profiler之类的工具.但严重停止担心GC.
我怎样才能提高性能?请参阅上面的代码片段.我不知道你的程序还在做什么.