我有一个监控无线电设备的相对较大的系统(迄今为止约25000行代码)。使用最新版本的ZedGraph显示图表等。程序使用C#在VS2010和Win7上编码。
- 当我从VS中运行程序时,它运行得很慢
- 当我从构建的EXE中运行程序时,它运行得很慢
- 当我通过Performance Wizard / CPU Profiler运行程序时,它运行得非常快。
- 当我从构建的EXE中运行程序,然后启动VS并将分析器附加到任何其他进程时,我的程序会加速!
我希望程序始终保持那样快!
解决方案已经在StackOverflow上提出,所有项目都设置为RELEASE,未托管代码调试已禁用,DEFINE DEBUG和TRACE常量也已禁用,代码优化-I tried either,警告级别-I tried either,抑制JIT - I tried either。
我认为问题不在我的代码中,因为如果我附加分析器到其他不相关的进程,它也会变快!
请帮帮我!我真的需要程序在任何地方都像在分析器中一样快速运行,因为这是关键业务应用程序,不能容忍性能问题...
更新1-8如下
--------------------Update1:--------------------
问题似乎与ZedGraph无关,因为我用自己的基本绘图替换了ZedGraph后,问题仍然存在。
--------------------Update2:--------------------
在虚拟机中运行程序时,程序仍然运行缓慢,并且从主机计算机运行分析器也不能使其变快。
--------------------Update3:--------------------
启动屏幕捕获到视频中也会加速程序!
--------------------Update4:--------------------
如果我打开英特尔显卡驱动程序设置窗口(此窗口:http://www.intel.com/support/graphics/sb/img/resolution_new.jpg),然后不断将光标悬停在按钮上,使它们发光等,我的程序就会加速!。但是如果运行GPUz或Kombustor,则不会加速,因此GPU不会降频-它保持稳定的850MHz。
--------------------Update5:--------------------
在不同的机器上进行测试:
- 在我的Core i5-2400S with Intel HD2000上,UI 运行缓慢,CPU 使用率为 ~15%。
- 在同事的Core 2 Duo with Intel G41 Express上,UI 运行快,但CPU 使用率为 ~90%(这也不正常)
- 在Core i5-2400S with dedicated Radeon X1650上,UI运行非常快,CPU使用率为 ~50%。
--------------------Update6:--------------------
我的一部分代码显示如何更新单个图表(graphFFT
是ZedGraphControl
的封装,以便于使用):
public void LoopDataRefresh() //executes in a new thread
{
while (true)
{
while (!d.Connected)
Thread.Sleep(1000);
if (IsDisposed)
return;
//... other graphs update here
if (signalNewFFT && PanelFFT.Visible)
{
signalNewFFT = false;
#region FFT
bool newRange = false;
if (graphFFT.MaxY != d.fftRangeYMax)
{
graphFFT.MaxY = d.fftRangeYMax;
newRange = true;
}
if (graphFFT.MinY != d.fftRangeYMin)
{
graphFFT.MinY = d.fftRangeYMin;
newRange = true;
}
List<PointF> points = new List<PointF>(2048);
int tempLength = 0;
short[] tempData = new short[2048];
int i = 0;
lock (d.fftDataLock)
{
tempLength = d.fftLength;
tempData = (short[])d.fftData.Clone();
}
foreach (short s in tempData)
points.Add(new PointF(i++, s));
graphFFT.SetLine("FFT", points);
if (newRange)
graphFFT.RefreshGraphComplete();
else if (PanelFFT.Visible)
graphFFT.RefreshGraph();
#endregion
}
//... other graphs update here
Thread.Sleep(5);
}
}
SetLine
是:
public void SetLine(String lineTitle, List<PointF> values)
{
IPointListEdit ip = zgcGraph.GraphPane.CurveList[lineTitle].Points as IPointListEdit;
int tmp = Math.Min(ip.Count, values.Count);
int i = 0;
while(i < tmp)
{
if (values[i].X > peakX)
peakX = values[i].X;
if (values[i].Y > peakY)
peakY = values[i].Y;
ip[i].X = values[i].X;
ip[i].Y = values[i].Y;
i++;
}
while(ip.Count < values.Count)
{
if (values[i].X > peakX)
peakX = values[i].X;
if (values[i].Y > peakY)
peakY = values[i].Y;
ip.Add(values[i].X, values[i].Y);
i++;
}
while(values.Count > ip.Count)
{
ip.RemoveAt(ip.Count - 1);
}
}
RefreshGraph
是:
public void RefreshGraph()
{
if (!explicidX && autoScrollFlag)
{
zgcGraph.GraphPane.XAxis.Scale.Max = Math.Max(peakX + grace.X, rangeX);
zgcGraph.GraphPane.XAxis.Scale.Min = zgcGraph.GraphPane.XAxis.Scale.Max - rangeX;
}
if (!explicidY)
{
zgcGraph.GraphPane.YAxis.Scale.Max = Math.Max(peakY + grace.Y, maxY);
zgcGraph.GraphPane.YAxis.Scale.Min = minY;
}
zgcGraph.Refresh();
}
--------------------更新7:--------------------
我刚刚用ANTS分析器运行了它。它告诉我,当程序快速运行时,ZedGraph
的刷新计数比运行缓慢时精确高出两倍。
以下是截图:
我发现非常奇怪的是,考虑到这些部分长度的微小差异,性能会以数学上的精度相差两倍。
此外,我升级了GPU驱动程序,但没有帮助。
--------------------更新8:--------------------
不幸的是,几天来,我无法再复现这个问题...我得到了持续的可以接受的速度(仍然比两周前在分析器中看到的速度稍慢),并且不受以前影响它的任何因素的影响 - 分析器、视频捕获或GPU驱动程序窗口。我仍然无法解释导致这个问题发生的原因...
Thread.Sleep
、Timer
等)都会更加准确。这可以解释速度提升的两种情况——例如,WPF应用程序在需要时(例如进行平滑动画时)会增加计时器分辨率,然后恢复它(当动画停止时)。分析器显然也希望有更准确的计时器。 - Luaan