Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=455591
在WinMain函数被执行之前,有一pd复杂的加载动作,q要执行一大段启动代码。运行程序MyApp.exeӞ操作pȝ的加载程序首先ؓ(f)q程分配一?GB的虚拟地址I间Q然后把E序MyApp.exe所占用的磁盘空间作拟内存映到q个4GB的虚拟地址I间中。一般情况下Q会(x)映射到虚拟地址I间?X00400000的位|。加载一个应用程序的旉比一般h所设想的要,因ؓ(f)加蝲一个PE文gq不是把q个文g整个一ơ性的从磁盘读到内存中Q而是单的做一个内存映,映射一个大文g和映一个小文g所p的时间相差无几。当?dng)真正执行文g中的代码Ӟ操作pȝq是要把存在于磁盘上的虚拟内存中的代码交换到物理内存(RAM)中。但是,q种交换也不是把整个文g所占用的虚拟地址I间一ơ性的全部从磁盘交换到物理内存中,操作pȝ?x)根据需要和内存占用情况交换一|多页。当?dng)q种交换是双向的Q即存在于物理内存中的一部分当前没有被用的也可能被交换到盘中?/p>
接着Q系l在内核中创E对象和ȝE对象以?qing)其它内宏V?/p>
然后操作pȝ的加载程序搜索PE文g中的引入表,加蝲所有应用程序所使用的动态链接库。对动态链接库的加载与对应用程序的加蝲完全cM?/p>
再接着Q操作系l执行PE文g首部所指定地址处的代码Q开始应用程序主U程的执行。首先被执行的代码ƈ不是MyApp中的WinMain函数Q而是被称为C Runtime startup code的WinMainCRTStartup函数Q该函数是连接时p接程序附加到文gMyApp.exe中的。该函数得到新进E的全部命o(h)行指针和环境变量的指针,完成一些Cq行时全局变量以及(qing)Cq行时内存分配函数的初始化工作。如果用C++~程Q还要执行全局cd象的构造函数。最后,W(xu)inMainCRTStartup函数调用WinMain函数?/p>
WinMainCRTStartup函数传给WinMain函数?个参数分别ؓ(f)QhInstance、hPrevInstance、lpCmdline、nCmdShow?/p>
hInstanceQ该q程所对应的应用程序当前实例的句柄。WinMainCRTStartup函数通过调用GetStartupInfo函数获得该参数的倹{该参数实际上是应用E序被加载到q程虚拟地址I间的地址Q通常情况下,对于大多数进E,该参数L0X00400000?/p>
hPrevInstanceQ应用程序前一实例的句柄。由于Win32应用E序的每一个实例Lq行在自q独立的进E地址I间中,因此Q对于Win32应用E序QW(xu)inMainCRTStartup函数传给该参数的值LNULL。如果应用程序希望知道是否有另一个实例在q行Q可以通过U程同步技术,创徏一个具有唯一名称的互斥量Q通过(g)这个互斥量是否存在可以知道是否有另一个实例在q行?/p>
lpCmdlineQ命令行参数的指针。该指针指向一个以0l尾的字W串Q该字符串不包括应用E序名?/p>
nCmdShowQ指定如何显C应用程序窗口。如果该E序通过在资源管理器中双d标运行,W(xu)inMainCRTStartup函数传给该参数的gؓ(f)SW_SHOWNORMAL。如果通过在另一个应用程序中调用CreatProcess函数q行Q该参数由CreatProcess函数的参数l(f)pStartupInfo(STARTUPINFO.wShowWindow)指定?/p>
本文档深入分析了(jin)std::dequeQƈ提供?jin)一个指导思想Q当考虑到内存分配和执行性能的时候,使用std::deque要比std::vector好?br>
函数 |
描述 |
c.assign(beg,end) c.assign(n,elem) |
[beg; end)区间中的数据赋值给c?br>n个elem的拷贝赋值给c?/td> |
c.at(idx) |
传回索引idx所指的数据Q如果idx界Q抛出out_of_range?/td> |
c.back() |
传回最后一个数据,不检查这个数据是否存在?/td> |
c.begin() |
传回q代器重的可一个数据?/td> |
c.clear() |
U除容器中所有数据?/td> |
deque<Elem> c deque<Elem> c1(c2) Deque<Elem> c(n) Deque<Elem> c(n, elem) Deque<Elem> c(beg,end) c.~deque<Elem>() |
创徏一个空的deque?br>复制一个deque?br>创徏一个dequeQ含有n个数据,数据均已~省构造生?br>创徏一个含有n个elem拯的deque?br>创徏一个以[beg;end)区间的deque?br>销毁所有数据,释放内存?/td> |
c.empty() |
判断容器是否为空?/td> |
c.end() |
指向q代器中的最后一个数据地址?/td> |
c.erase(pos) c.erase(beg,end) |
删除pos位置的数据,传回下一个数据的位置?br>删除[beg,end)区间的数据,传回下一个数据的位置?/td> |
c.front() |
传回C个数据?/td> |
get_allocator |
使用构造函数返回一个拷贝?/td> |
c.insert(pos,elem) c.insert(pos,n,elem) c.insert(pos,beg,end) |
在pos位置插入一个elem拯Q传回新数据位置?br>在pos位置插入>n个elem数据。无q回倹{?br>在pos位置插入在[beg,end)区间的数据。无q回倹{?/td> |
c.max_size() |
q回容器中最大数据的数量?/td> |
c.pop_back() |
删除最后一个数据?/td> |
c.pop_front() |
删除头部数据?/td> |
c.push_back(elem) |
在尾部加入一个数据?/td> |
c.push_front(elem) |
在头部插入一个数据?/td> |
c.rbegin() |
传回一个逆向队列的第一个数据?/td> |
c.rend() |
传回一个逆向队列的最后一个数据的下一个位|?/td> |
c.resize(num) |
重新指定队列的长度?/td> |
c.size() |
q回容器中实际数据的个数?/td> |
C1.swap(c2) Swap(c1,c2) |
c1和c2元素互换?br>同上操作?/td> |
函数 |
描述 |
operator[] |
q回容器中指定位|的一个引用?/td> |
#include <deque> #include <fstream> #include <string> #include <vector> static enum modes { FM_INVALID = 0, FM_VECTOR, FM_DEQUE }; class CVectorDequeTest { public: CVectorDequeTest(); void ReadTestFile(const char* szFile, int iMode) { char buff[0xFFFF] = {0}; std::ifstream inFile; inFile.open(szFile); while(!inFile.eof()) { inFile.getline(buff, sizeof(buff)); if(iMode == FM_VECTOR) m_vData.push_back(buff); else if(iMode == FM_DEQUE) m_dData.push_back(buff); } inFile.close(); } virtual ~CVectorDequeTest(); protected: std::vector<std::string> m_vData; std::deque<std::string> m_dData; }; |
CPU | 1.8 GHz Pentium 4 |
内存 | 1.50 GB |
操作pȝ | W2K-SP4 |
文g中的行数 | 9874 |
q_每行字母个数 |
1755.85 |
L件的ơ数 |
45 |
d插入的数据个?/td> | 444330 |
![]() |
![]() |
![]() |
实验二—?vector::reserve()的资?/strong>
m_vData.reserve(1000000); |
CPU |
1.8 GHz Pentium 4 |
内存 |
1.50 GB |
操作pȝ |
W2K-SP4 |
文g中的行数 |
9874 |
q_每行字母个数 |
1755.85 |
L件的ơ数 |
70 |
d插入的数据个?br> | 691180 |
![]() |
![]() |
![]() |
Vector |
Deque |
||||||||||||||||||||
|
|
for(xRun=0; xRun<NUMBER_OF_XRUNS; xRun++) { df = new CVectorDequeTest; elapsed_time = 0; for(i=0; i<NUMBER_OF_RUNS*xRun; i++) { cout << "Deque - Run " << i << " of " << NUMBER_OF_RUNS*xRun << "... "; df->ReadTestFile("F:\\huge.csv",DF_DEQUE); deque_data.push_back(datapoint()); deque_data.back().time_to_read = df->GetProcessTime(); elapsed_time += deque_data.back().time_to_read; deque_data.back().elapsed_time = elapsed_time; cout << deque_data.back().time_to_read << " seconds\n"; } vnElements.push_back(df->GetDequeSize()); cout << "\n\nDeleting... "; del_deque.Start(); delete df; del_deque.Stop(); cout << del_deque.GetDuration()/1000000.0 << " seconds.\n\n"; vTimeToDelete.push_back(del_deque.GetDuration()/1000000.0); } |
![]() |
deque Results |
|
Mean |
0.007089269 sec |
Maximum |
11.02838496 sec |
Minimum |
-15.25901667 sec |
Std. Dev |
3.3803636 sec |
6-Sigma |
20.2821816 sec |
![]() |
vector Results |
|
Mean |
-0.007122715sec |
Maximum |
0.283452127 sec |
Minimum |
-0.26724459sec |
Std. Dev |
0.144572356sec |
6-Sigma |
0.867434136sec |
![]() |
![]() |
|
|
||||||||||||||||||||||
|
|