一次优化实践
一、优化方法
什么时候开始优化:程序性能出现问题时
优化哪里:找到程序性能瓶颈,优化瓶颈处。
二、实践
当有1W根杆件时,我的程序生成模型要用90秒时间。
使用VS2008自带的性能分析器,分析三维渲染模块。得到如下数据
函数 |
非独占样本数 |
allocator<double>::deallocate |
155 |
_Destroy(CirculatorIterator_VertexWrap) |
147 |
vector_Destroy_VertexWrap |
94 |
SimplePolygonCommonExtrude::Extrude |
82 |
VPolygon2D::Triangulate_1 |
79 |
MakeColumn::MakeVerticalColumn |
71 |
VPolygon2D::Triangulate_2 |
70 |
SpliteEdge |
54 |
SpliteEdge(class VMath::THalfEdge *) |
48 |
partition_y_mono_handle_regular_vertex |
34 |
YMonotonePolygonTriangulation::Triangulation |
33 |
Std::_Checked_base<_Vector_iterator<THalfEdge *> |
28 |
VPoint2D::VPoint2D(class VMath::VPoint2D const &) |
28 |
stdext::unchecked_uninitialized_copy<class std::_Vector_iterator<class MTS::VoShape * |
27 |
_Vector_iterator<class VMath::VertexWrap_::_Vector_iterator |
23 |
vector<class VMath::THalfEdge *::_Tidy |
23 |
_Vector_const_iterator<class VMath::VertexWrap,::_Vector_const_iterator |
22 |
std::vector<class VMath::HalfEdgeDS *::operator[] |
21 |
结合代码,找到了程序瓶颈处:VPolygon2D::Triangulate函数.有多少根杆件就要调用多少次三角化函数。
程序特点:将同样的截面三角化了n次,实际上只要三角化1次就够了。
解决方法:从三角化n次,降到<<n次。
使用VS2008自带的性能分析器,分析渲染模块。得到如下数据。
当前函数
函数名 |
非独占样本数 |
独占样本数 |
非独占样本数 % |
独占样本数 % |
DlgNew3D::OnCreate |
158 |
0 |
21.41 |
0.00 |
DlgNew3D::AddMember |
150 |
20.33 |
||
DlgNew3D::AddHorizontalSimpleBeam |
101 |
13.69 |
||
DlgNew3D::GetSectionInfo |
91 |
12.74 |
函数名 |
非独占样本数 |
独占样本数 |
非独占样本数 % |
独占样本数 % |
BuildManager::ProcessAdded |
44 |
5.96 |
||
MakeSimpleBeam |
28 |
|||
SimplePolygonCommonExtrude |
24 |
|||
SimpleSection::AppendPoint |
24 |
GetSectionInfo 拷贝了相同的section数次,可以优化这点。在截面表中添加VPlolygon2D对象就可以了。
由杆件截面ID得到截面对象指针,也可以由截面对象指针
按上述方法优化程序,1W根杆件的造型时间为5秒。满足性能要求。停止优化。
三、使用vs2008性能分析器需要了解的知识:
采样分析技术按时间间隔获取程序执行过程的快照。采样收集的数据少于检测,因此可在较长的方案中运行它。默认情况下,
如果应用程序的性能受CPU速度限制,采样将通知你哪些函数正在使用大多数CPU时间。
检测分析技术将诊断探测插入到正在分析的程序中。将公为检测的二进制文件和从这些文件直接调用的外部函数收集分析数据。
检测收集的数据多于采样。
非独占样本数
执行目标函数期间收集的样本总数。//程序运行期间某函数采样数的总和
这包括直接执行函数代码期间收集的样本和执行目标函数调用的子函数期间收集的样本。
举例
void test1()
{
//直接执行函数代码期间收集的样本
int i=0;
i++;
//执行目标函数调用的子函数期间收集的样本
test2();
test3();
}
独占样本数:直接执行目标函数的指令期间收集的样本数。//在执行这个函数期间的采样数。
独占样本不包括执行目标函数调用的函数期间收集的样本。
非独占百分比:函数或数据范围的非独占样本占分析运行中非独占样本总数的百分比。
独占百分比:函数或数据范围的独占样本占分析运行中独占样本总数的百分比。