• 
    

    
    

      99热精品在线国产_美女午夜性视频免费_国产精品国产高清国产av_av欧美777_自拍偷自拍亚洲精品老妇_亚洲熟女精品中文字幕_www日本黄色视频网_国产精品野战在线观看

      ?

      提高VC 6.0中函數(shù)執(zhí)行時(shí)間測試可信度的研究

      2019-07-17 06:45:12張合花張全法
      中州大學(xué)學(xué)報(bào) 2019年3期
      關(guān)鍵詞:運(yùn)算符測試工具調(diào)用

      張合花,張全法,馬 冰

      (鄭州大學(xué) 物理工程學(xué)院,河南 鄭州 450001)

      C/C++程序可以獲得很高的運(yùn)行速度,而許多情況下對程序的運(yùn)行速度有著很高的要求,特別是需要實(shí)時(shí)處理大量信息的時(shí)候。但是C/C++程序?qū)懗龊笸€需要進(jìn)行優(yōu)化來提高速度。常用的優(yōu)化技巧包括:盡量采用自增、自減運(yùn)算和賦值縮寫,利用指針法訪問數(shù)組,合理使用內(nèi)聯(lián)函數(shù)和寄存器變量,采用位運(yùn)算代替一些乘法或除法運(yùn)算,盡可能將浮點(diǎn)數(shù)運(yùn)算轉(zhuǎn)化為整數(shù)運(yùn)算,正確運(yùn)用內(nèi)存拷貝函數(shù),等等[1-4]。

      對程序優(yōu)化后通常需要測試運(yùn)行速度,以便確認(rèn)取得了優(yōu)化效果并了解優(yōu)化程度。文獻(xiàn)[5]通過編程測試程序運(yùn)行時(shí)間,這非常麻煩,并且僅適用于它小于一個(gè)時(shí)間片。實(shí)際上,VC 6.0作為許多高校教學(xué)平臺(tái)程序員慣用的開發(fā)工具,其內(nèi)部集成了一個(gè)使用非常方便的測試工具,可以用來測試程序中各個(gè)函數(shù)的執(zhí)行時(shí)間,已經(jīng)在不少方面獲得了應(yīng)用[3-4]。然而實(shí)驗(yàn)證明,在某些情況下該工具所給的測試數(shù)據(jù)非常不可靠。為此,提出了獲得具有更高可信度之函數(shù)執(zhí)行時(shí)間的方法。

      1 實(shí)驗(yàn)用程序及集成測試工具使用方法

      1.1 實(shí)驗(yàn)用程序

      利用VC 6.0新建Win32 Console Application類型的空白項(xiàng)目,然后添加頭文件MyClass.h,內(nèi)容如下(為節(jié)省篇幅,對代碼做了盡可能的簡化,并利用先注釋掉部分代碼再逐步修改的方法,將本研究所用的多個(gè)程序揉和在了一起,下同):

      externint x;

      classA{public:

      //A(){a = x++;}

      //標(biāo)記①

      //~A(){a = 0;}

      //標(biāo)記②

      //A();

      //標(biāo)記③

      //~A();

      //標(biāo)記④

      int a;};

      class B{int b;};

      接著添加源文件MyClass.cpp,內(nèi)容如下:

      #include "MyClass.h"

      //A::A(){a = x++;}

      //標(biāo)記⑤

      //A::~A(){a = 0;}

      //標(biāo)記⑥

      最后添加源文件main.cpp,內(nèi)容如下:

      #include

      #include "MyClass.h"

      using namespace std;

      int x = 1;

      voidfunc(){A *p = new A[100];delete[]p;}

      void consume(){B *p = new B[100];delete[]p;}

      void main(){

      for(int i = 0; i < 10000; i++){

      //標(biāo)記⑦

      //consume();

      //標(biāo)記⑧

      func();}}

      //標(biāo)記⑨

      程序中,func()函數(shù)先利用矢量形式的new運(yùn)算符動(dòng)態(tài)創(chuàng)建變量數(shù)組,再利用矢量形式的delete運(yùn)算符動(dòng)態(tài)釋放內(nèi)存,為主要測試對象。consume()函數(shù)的功能與它相同,不過創(chuàng)建對象時(shí)所用類型不同,其作用后面說明。

      1.2 集成測試工具使用方法

      利用VC 6.0提供的工具測試函數(shù)執(zhí)行時(shí)間的完整步驟是:①單擊Build彈出菜單上的Set Active Configuration菜單項(xiàng),設(shè)置程序的當(dāng)前編譯、運(yùn)行版本為Debug或Release版。②同時(shí)按下Alt和F7鍵,在彈出的對話框的Link選項(xiàng)卡上,選中Enable Profiling復(fù)選框。③單擊Build彈出菜單上的Rebuild All菜單項(xiàng),編譯、鏈接程序。④單擊Build彈出菜單上的Profile菜單項(xiàng),在彈出的對話框上確保單選按鈕Function timing處于選中狀態(tài),再點(diǎn)擊OK按鈕啟動(dòng)測試。程序退出后在Output面板上的輸出窗口即可看到各函數(shù)的執(zhí)行時(shí)間,此后步驟可以簡化,不必每次都完整進(jìn)行。

      輸出結(jié)果中,F(xiàn)unc Time稱為函數(shù)的部分總執(zhí)行時(shí)間,它是多次調(diào)用所需時(shí)間的總和,但是不包括在其內(nèi)部調(diào)用其他函數(shù)所需時(shí)間。Func+Child Time稱為總執(zhí)行時(shí)間,它是多次調(diào)用所需時(shí)間的總和,且包括在其內(nèi)部調(diào)用其他函數(shù)所需時(shí)間,將其除以調(diào)用次數(shù)即為前面所說的函數(shù)執(zhí)行時(shí)間。Hit Count為函數(shù)調(diào)用次數(shù),F(xiàn)unction為對應(yīng)的函數(shù)。

      2 問題的發(fā)現(xiàn)

      2.1 發(fā)現(xiàn)問題所用程序

      上述程序稱為設(shè)計(jì)1。在其基礎(chǔ)上:將標(biāo)記①所在行前面的注釋符號刪除后的程序稱為設(shè)計(jì)2;將標(biāo)記②所在行前面的注釋符號刪除后的程序稱為設(shè)計(jì)3;將這兩行前面的注釋符號同時(shí)刪除后的程序稱為設(shè)計(jì)4。

      按照C++編程思想,new運(yùn)算符內(nèi)部首先調(diào)用malloc()函數(shù)動(dòng)態(tài)分配內(nèi)存,再調(diào)用自定義類型的構(gòu)造函數(shù)初始化對象;delete運(yùn)算符內(nèi)部首先調(diào)用自定義類型的析構(gòu)函數(shù)清除對象,再調(diào)用free()函數(shù)動(dòng)態(tài)釋放內(nèi)存[6]。因此,可用來比較沒有自定義構(gòu)造函數(shù)和析構(gòu)函數(shù)、僅有前者、僅有后者、二者皆有等情況下func()函數(shù)執(zhí)行時(shí)間的差異。

      2.2 實(shí)驗(yàn)條件與測試結(jié)果

      實(shí)驗(yàn)所用計(jì)算機(jī)型號為Lenovo G50-70m,操作系統(tǒng)為Win10,其CPU為Intel Core i3-4030U,主頻為1.90 GHz,下同。分別在Debug和Release版下對func()函數(shù)的總執(zhí)行時(shí)間測試10次。對于Release版,優(yōu)化策略為最大速度,下同。

      由于操作系統(tǒng)的多任務(wù)特性,每次運(yùn)行程序同一函數(shù)的執(zhí)行時(shí)間存在明顯差異。為此采取的措施有:利用for循環(huán)增加函數(shù)總執(zhí)行時(shí)間的有效位數(shù)并減小波動(dòng)幅度,若某次測試結(jié)果偏離平均值太多則舍棄重測,對總執(zhí)行時(shí)間測試多次求平均值,等等。得到測試數(shù)據(jù)后計(jì)算平均總執(zhí)行時(shí)間及標(biāo)準(zhǔn)偏差,結(jié)果如表1所示。VC 6.0給的時(shí)間以ms為單位,小數(shù)點(diǎn)后面有3位數(shù)字??紤]到數(shù)據(jù)的波動(dòng)性,僅給出了2~3位數(shù)字,下同。

      表1 設(shè)計(jì)1~4中func()函數(shù)的總執(zhí)行時(shí)間 ms

      2.3 測試結(jié)果分析

      設(shè)計(jì)2~4的平均總執(zhí)行時(shí)間均比設(shè)計(jì)1的對應(yīng)值大許多。這是因?yàn)闆]有自定義構(gòu)造函數(shù)和析構(gòu)函數(shù)時(shí),new運(yùn)算符會(huì)調(diào)用默認(rèn)構(gòu)造函數(shù),delete運(yùn)算符會(huì)調(diào)用默認(rèn)析構(gòu)函數(shù),而默認(rèn)構(gòu)造函數(shù)和析構(gòu)函數(shù)皆為空函數(shù),執(zhí)行速度一定比自定義構(gòu)造函數(shù)和析構(gòu)函數(shù)快許多。Release版的平均總執(zhí)行時(shí)間小于Debug版的對應(yīng)值。這是因?yàn)镈ebug版需要嵌入調(diào)試信息而Release版不需要。

      Debug版下設(shè)計(jì)2和3的平均總執(zhí)行時(shí)間大約相等。這是因?yàn)樽远x構(gòu)造函數(shù)和析構(gòu)函數(shù)差別很小,二者的執(zhí)行時(shí)間差別應(yīng)該不大,而默認(rèn)構(gòu)造函數(shù)和析構(gòu)函數(shù)的執(zhí)行時(shí)間差別也應(yīng)該不大。Debug版下設(shè)計(jì)4的平均總執(zhí)行時(shí)間大約為設(shè)計(jì)2與3平均總執(zhí)行時(shí)間之和再減去設(shè)計(jì)1的平均總執(zhí)行時(shí)間。根據(jù)上述分析,正應(yīng)該如此。問題是,Release版下設(shè)計(jì)3的平均總執(zhí)行時(shí)間大約為設(shè)計(jì)2的20倍,設(shè)計(jì)4的平均總執(zhí)行時(shí)間大約為設(shè)計(jì)3的2倍,這不符合預(yù)期。而Release版下函數(shù)的執(zhí)行時(shí)間通常是最應(yīng)該關(guān)心的。

      3 假設(shè)與驗(yàn)證

      3.1 引起問題之原因的假設(shè)

      經(jīng)過仔細(xì)觀察發(fā)現(xiàn),Release版下對于設(shè)計(jì)2進(jìn)行測試時(shí),在VC 6.0給的結(jié)果中找不到執(zhí)行自定義構(gòu)造函數(shù)的總執(zhí)行時(shí)間,對于設(shè)計(jì)3有自定義析構(gòu)函數(shù)的總執(zhí)行時(shí)間,對于設(shè)計(jì)4二者皆有。然而很容易證明,對于設(shè)計(jì)2程序運(yùn)行時(shí)確實(shí)調(diào)用了自定義構(gòu)造函數(shù)。于是可以假設(shè):對于使用了矢量形式之new和delete運(yùn)算符的函數(shù),測試其Release版執(zhí)行時(shí)間時(shí),測試工具在僅有自定義構(gòu)造函數(shù)情況下未統(tǒng)計(jì)自定義構(gòu)造函數(shù)的執(zhí)行時(shí)間。

      3.2 假設(shè)的具體化

      為了使假設(shè)更具體,在設(shè)計(jì)1的基礎(chǔ)上,將標(biāo)記③和⑤所在行前面的注釋符號同時(shí)刪除后的程序稱為設(shè)計(jì)5;將標(biāo)記④和⑥所在行前面的注釋符號同時(shí)刪除后的程序稱為設(shè)計(jì)6;將這四行前面的注釋符號同時(shí)刪除后的程序稱為設(shè)計(jì)7。設(shè)計(jì)5~7與設(shè)計(jì)2~4的區(qū)別在于,自定義構(gòu)造函數(shù)和(或)析構(gòu)函數(shù)皆由內(nèi)聯(lián)成員函數(shù)變成了非內(nèi)聯(lián)成員函數(shù)。按照同樣的方法對設(shè)計(jì)1和設(shè)計(jì)5~7中func()函數(shù)的總執(zhí)行時(shí)間進(jìn)行測試和計(jì)算,結(jié)果如表2所示。

      表2 設(shè)計(jì)1和5~7中func()函數(shù)的總執(zhí)行時(shí)間 ms

      此時(shí)Release版下設(shè)計(jì)5和6的平均總執(zhí)行時(shí)間大約相等,設(shè)計(jì)7的平均總執(zhí)行時(shí)間也大約為設(shè)計(jì)5與6平均總執(zhí)行時(shí)間之和再減去設(shè)計(jì)1的平均總執(zhí)行時(shí)間。因此,將前述假設(shè)具體化為:對于使用了矢量形式之new和delete運(yùn)算符的函數(shù),測試其Release版執(zhí)行時(shí)間時(shí),測試工具在僅有內(nèi)聯(lián)自定義構(gòu)造函數(shù)情況下,未統(tǒng)計(jì)自定義構(gòu)造函數(shù)的執(zhí)行時(shí)間。若果真如此,將設(shè)計(jì)2中func()函數(shù)在Release版下的總執(zhí)行時(shí)間近似取為168 ms,將比由測試工具所給數(shù)據(jù)得到的8.0 ms具有更高的可信度。

      3.3 實(shí)驗(yàn)對假設(shè)的支持

      假設(shè)的正確性必須通過人工測試來驗(yàn)證。人工測試時(shí)必須設(shè)法讓函數(shù)的總執(zhí)行時(shí)間足夠長,從而使得人工測試誤差小到可以容許的程度。為此,將設(shè)計(jì)1中標(biāo)記⑦所在行的10 000改為10 000 000,此時(shí)的程序稱為設(shè)計(jì)Ⅰ。在設(shè)計(jì)Ⅰ的基礎(chǔ)上進(jìn)行上述修改,由設(shè)計(jì)2得到設(shè)計(jì)Ⅱ,以此類推,直到得到設(shè)計(jì)Ⅶ。另外注意,人工只能直接測試整個(gè)程序即main()函數(shù)的總執(zhí)行時(shí)間。

      為了進(jìn)行比較,先利用測試工具按照上述方法測試main()函數(shù)的總執(zhí)行時(shí)間。不同的是僅測試1次且不再計(jì)算平均值及標(biāo)準(zhǔn)偏差。這是因?yàn)榇藭r(shí)完成一次測試所需的時(shí)間很長,例如對于設(shè)計(jì)Ⅶ測試一次耗時(shí)長達(dá)十幾分鐘,主要影響因素是測試工具本身需要時(shí)間。測試結(jié)果如表3所示。

      表3 設(shè)計(jì)Ⅰ~Ⅶ中main()函數(shù)的總執(zhí)行時(shí)間 s

      再利用一款蘋果手機(jī)上的秒表功能進(jìn)行人工測試,對于每個(gè)設(shè)計(jì)測試10次,然后計(jì)算平均值及標(biāo)準(zhǔn)偏差,結(jié)果在表3中同時(shí)給出。為方便操作,利用工具欄的快捷按鈕啟動(dòng)程序的同時(shí)讓秒表開始計(jì)時(shí),出現(xiàn)Press any key to continue后停止計(jì)時(shí)。另外發(fā)現(xiàn),每當(dāng)程序修改后啟動(dòng)運(yùn)行時(shí),前幾次往往明顯偏慢,需要跳過。

      由于main()函數(shù)的部分執(zhí)行時(shí)間很短(參見后面實(shí)驗(yàn)結(jié)果),即使將其總執(zhí)行時(shí)間視為func()函數(shù)的總執(zhí)行時(shí)間誤差也不是很大。根據(jù)表3中的數(shù)據(jù)可知:采用測試工具時(shí)調(diào)用次數(shù)變?yōu)橐郧暗?000倍,相應(yīng)的總執(zhí)行時(shí)間也大約為以前的1000倍,這符合預(yù)期,不算很大的偏差主要是數(shù)據(jù)波動(dòng)性的影響,main()函數(shù)部分執(zhí)行時(shí)間的影響并不大;人工測試時(shí),對于Release版,無論是內(nèi)聯(lián)的還是非內(nèi)聯(lián)的,自定義構(gòu)造函數(shù)對執(zhí)行時(shí)間的貢獻(xiàn)與自定義析構(gòu)函數(shù)相差不多。這是對所作假設(shè)的支持。

      3.4 測試工具的可信度問題

      對實(shí)驗(yàn)數(shù)據(jù)的進(jìn)一步分析發(fā)現(xiàn),即使所作假設(shè)成立,測試工具所給數(shù)據(jù)的可信度也值得懷疑。根據(jù)測試工具所給數(shù)據(jù):設(shè)計(jì)Ⅰ~Ⅶ中main()函數(shù)總執(zhí)行時(shí)間之比與設(shè)計(jì)1~7中func()函數(shù)總執(zhí)行時(shí)間之比基本一樣,在Debug和Release版下分別約為1252550252550,124080404080;如果認(rèn)為所作假設(shè)成立,Release版下的比值大約為1404080404080;對于相同設(shè)計(jì),Debug版的總執(zhí)行時(shí)間不超過Release版的2倍。

      然而根據(jù)人工測試數(shù)據(jù):設(shè)計(jì)Ⅰ~Ⅶ中main()函數(shù)總執(zhí)行時(shí)間之比在Debug和Release版下卻大約皆為155105510;對于相同設(shè)計(jì),Debug版的總執(zhí)行時(shí)間大約為Release版的5倍。將數(shù)據(jù)的波動(dòng)性、main()函數(shù)的部分執(zhí)行時(shí)間、測試工具運(yùn)行所需的時(shí)間以及人工測試時(shí)的反應(yīng)速度等因素之影響加在一起,都不足以造成與測試工具所給數(shù)據(jù)之間如此大的差別。雖然這不否定所作假設(shè),但它確實(shí)可能是VC 6.0提供的測試工具內(nèi)部的又一個(gè)Bug,使得它在特定條件下給的結(jié)果不可信,必須進(jìn)行人工測試才能夠得到可信的結(jié)果。

      4 獲取高可信度的測試數(shù)據(jù)

      4.1 獲取任意函數(shù)執(zhí)行時(shí)間的方法

      人工獲取任意函數(shù)執(zhí)行時(shí)間的方法只能是間接的:程序整體完成后,測試main()函數(shù)的總執(zhí)行時(shí)間T1(亦即它的執(zhí)行時(shí)間,因沒有通過循環(huán)多次調(diào)用它);然后將對被測試函數(shù)的調(diào)用注釋掉,再次測試main()函數(shù)(其中可能包含對其他函數(shù)的必要調(diào)用)的總執(zhí)行時(shí)間T2;于是,被測試函數(shù)的總執(zhí)行時(shí)間T=T1-T2,執(zhí)行時(shí)間等于T除以調(diào)用次數(shù)。若T1比較小,減小其測試誤差的方法如前所述。若T2比較小則可以通過調(diào)用“耗時(shí)函數(shù)”來減小其測試誤差。這種耗時(shí)函數(shù)本身沒有意義,但是總執(zhí)行時(shí)間比較長,而且在測試T1和T2時(shí)不變。

      4.2 實(shí)驗(yàn)結(jié)果

      在設(shè)計(jì)Ⅰ的基礎(chǔ)上,將標(biāo)記⑧所在行前面的注釋符號刪除以添加對耗時(shí)函數(shù)consume()的調(diào)用,此時(shí)的程序稱為設(shè)計(jì)ⅰ。在設(shè)計(jì)ⅰ的基礎(chǔ)上進(jìn)行上述修改,由設(shè)計(jì)2得到設(shè)計(jì)ⅱ,以此類推,直到得到設(shè)計(jì)ⅶ,再將標(biāo)記⑨所在行對func()函數(shù)的調(diào)用(注意不包括后面的兩個(gè)右花括號)注釋掉,此時(shí)的程序稱為設(shè)計(jì)ⅷ。然后按照上述方法人工測試并計(jì)算平均值及標(biāo)準(zhǔn)偏差,結(jié)果如表4所示。

      表4 設(shè)計(jì)ⅰ~ⅷ中main()函數(shù)的總執(zhí)行時(shí)間 s

      將表4中設(shè)計(jì)ⅰ~ⅶ的T1減去設(shè)計(jì)ⅷ的T2,得到設(shè)計(jì)ⅰ~ⅶ中func()函數(shù)的總執(zhí)行時(shí)間Tⅰ~Tⅶ,如表5所示。

      表5 設(shè)計(jì)ⅰ~ⅶ中func()函數(shù)的總執(zhí)行時(shí)間 s

      將表5中的結(jié)果與表3中的人工測試結(jié)果進(jìn)行比較可知,main()函數(shù)的部分執(zhí)行時(shí)間很短,如果不添加對耗時(shí)函數(shù)的調(diào)用,人工直接測試將非常困難。但它的影響還是有的,將其影響剔除后可以提高測試結(jié)果的可信度。

      4.3 關(guān)于操作系統(tǒng)多任務(wù)特性的影響

      若按照本文提出的方法測試函數(shù)的執(zhí)行時(shí)間,其中將包含程序運(yùn)行過程中被其他任務(wù)中斷所消耗的時(shí)間。文獻(xiàn)[7]認(rèn)為不應(yīng)該包含它,但是本文認(rèn)為恰好應(yīng)該包含它,因?yàn)樵谶@樣的操作系統(tǒng)中被中斷是不可避免的,只有包含它才能反映實(shí)際情況。

      5 結(jié)語

      本文通過實(shí)驗(yàn)證明了VC 6.0提供的函數(shù)執(zhí)行時(shí)間測試工具對于使用了矢量形式之new和delete運(yùn)算符的函數(shù)存在問題:在Release版下當(dāng)僅有內(nèi)聯(lián)自定義構(gòu)造函數(shù)時(shí),沒有統(tǒng)計(jì)自定義構(gòu)造函數(shù)的執(zhí)行時(shí)間;無論Debug版還是Release版,其所給數(shù)據(jù)的可信度都太低。此時(shí),通過人工測試調(diào)用和不調(diào)用被測試函數(shù)時(shí)main()函數(shù)的總執(zhí)行時(shí)間,再取二者之差,并采取適當(dāng)?shù)拇胧┤缍啻窝h(huán)調(diào)用、添加調(diào)用耗時(shí)函數(shù)等減小測試誤差,可以得到較高可信度的測試數(shù)據(jù)。或許還有更多的類似情況尚未發(fā)現(xiàn),相信皆可以利用這種方法解決。

      猜你喜歡
      運(yùn)算符測試工具調(diào)用
      邊緣智力兒童及其智力測試工具的研究進(jìn)展
      老祖?zhèn)魇诨具\(yùn)算符
      核電項(xiàng)目物項(xiàng)調(diào)用管理的應(yīng)用研究
      LabWindows/CVI下基于ActiveX技術(shù)的Excel調(diào)用
      Http并發(fā)連接測試工具
      基于系統(tǒng)調(diào)用的惡意軟件檢測技術(shù)研究
      福祿克推出先進(jìn)的連接式測試工具系統(tǒng)
      C++運(yùn)算符重載剖析
      利用RFC技術(shù)實(shí)現(xiàn)SAP系統(tǒng)接口通信
      表達(dá)式求值及符號推導(dǎo)
      江山市| 庄河市| 延津县| 饶河县| 石屏县| 临潭县| 大关县| 汉中市| 涿州市| 穆棱市| 屏山县| 望谟县| 武定县| 永善县| 六安市| 自贡市| 蒙自县| 昭平县| 临桂县| 怀化市| 鄂州市| 池州市| 衡山县| 志丹县| 湖口县| 昌乐县| 临沭县| 辽源市| 碌曲县| 加查县| 驻马店市| 磐石市| 瑞丽市| 海盐县| 侯马市| 蓬溪县| 霞浦县| 奉化市| 手游| 合山市| 惠州市|