1. 程式人生 > 實用技巧 >C++程式碼優化之nim_duilib

C++程式碼優化之nim_duilib

前言

  • 使用nim_duilib關聯控制元件,優化後。的確減少了程式碼量,那麼,執行效率呢?
  • 時間執行的長短與硬體、軟體有關,以下內容僅為參考。

測試程式碼

  • 下面的程式碼,分為兩部分, 迴圈使用for,非迴圈則直接使用陣列索引
  • Release model執行測試結果

迴圈程式碼

ui::Button *pbtn_arr_[12] = { nullptr };
long long start = std::chrono::system_clock::now().time_since_epoch().count();

for (auto item : pbtn_arr_)
{
	find_control2(std::wstring(L"btn_blue"), item);
}

long long end = std::chrono::system_clock::now().time_since_epoch().count();
std::wstring sss =fmt::format(L"{}", (end-start));

執行結果

時間單位: 微秒(microsecond)

序號 間隔(毫秒)
1 8
2 7
3 8
4 8
5 8
6 8
7 8
8 7
9 7
10 8

.......
大約執行時間為 7.7微妙 左右

非迴圈程式碼

ui::Button *pbtn_arr_[12] = { nullptr };
long long start = std::chrono::system_clock::now().time_since_epoch().count();

pbtn_arr_[0]	= dynamic_cast<ui::Button*>(FindControl(L"btn_blue"));
pbtn_arr_[1]	= dynamic_cast<ui::Button*>(FindControl(L"btn_blue"));
pbtn_arr_[2]	= dynamic_cast<ui::Button*>(FindControl(L"btn_blue"));
pbtn_arr_[3]	= dynamic_cast<ui::Button*>(FindControl(L"btn_blue"));
pbtn_arr_[4]	= dynamic_cast<ui::Button*>(FindControl(L"btn_blue"));
pbtn_arr_[5]	= dynamic_cast<ui::Button*>(FindControl(L"btn_blue"));
pbtn_arr_[6]	= dynamic_cast<ui::Button*>(FindControl(L"btn_blue"));
pbtn_arr_[7]	= dynamic_cast<ui::Button*>(FindControl(L"btn_blue"));
pbtn_arr_[8]	= dynamic_cast<ui::Button*>(FindControl(L"btn_blue"));
pbtn_arr_[9]	= dynamic_cast<ui::Button*>(FindControl(L"btn_blue"));
pbtn_arr_[10]	= dynamic_cast<ui::Button*>(FindControl(L"btn_blue"));
pbtn_arr_[11]	= dynamic_cast<ui::Button*>(FindControl(L"btn_blue"));

long long end = std::chrono::system_clock::now().time_since_epoch().count();
std::wstring sss =fmt::format(L"{}", (end-start));

執行結果

時間單位: 微秒(microsecond)

序號 間隔(毫秒)
1 21
2 21
3 23
4 22
5 23
6 21
7 21
8 22
9 22
10 23

.......
大約執行時間為 22微妙 左右

結果

可見,如果能用迴圈,能大幅縮短程式執行時間,採用for迴圈後,降低執行時間約為 14 微妙。

程式碼分析

分析下面程式碼的特點

pbtn_arr_[10]	= dynamic_cast<ui::Button*>(FindControl(L"btn_blue"));
pbtn_arr_[11]	= dynamic_cast<ui::Button*>(FindControl(L"btn_blue"));

其中,每次需要繫結控制元件時,都需重複下面的程式碼

  = 
  dynamic_cast<
  >(FindControl();

顯然,我們可以把它進一步優化。
於是將上面的程式碼pbtn_arr_[10] = dynamic_cast<ui::Button*>(FindControl(L"btn_blue"));改為下面的形式:

find_control2(std::wstring(L"btn_blue"), btn_arr[11]);

其中,find_control2程式碼如下:

<template<typename T>
void find_control2(const std::wstring&& str_name, T& args)
{
	// 取得傳進來的引數型別
	using ele_type2 =  typename std::decay<T>::type;

	// 讀取xml檔案中的控制元件
	ui::Control* pctrl = nullptr;
	pctrl = FindControl(str_name);
	if (pctrl)
	{
		// 轉為目標型別指標
		args = dynamic_cast<ele_type2>(pctrl);
	}
}

改進後的效率執行如何呢?

改進後的時間測試

優化前

ui::Button *btn_arr[12] = { nullptr };
long long start = std::chrono::system_clock::now().time_since_epoch().count();

btn_arr[0]	= dynamic_cast<ui::Button*>(FindControl(L"btn_blue"));
btn_arr[1]	= dynamic_cast<ui::Button*>(FindControl(L"btn_blue"));
btn_arr[2]	= dynamic_cast<ui::Button*>(FindControl(L"btn_blue"));
btn_arr[3]	= dynamic_cast<ui::Button*>(FindControl(L"btn_blue"));
btn_arr[4]	= dynamic_cast<ui::Button*>(FindControl(L"btn_blue"));
btn_arr[5]	= dynamic_cast<ui::Button*>(FindControl(L"btn_blue"));
btn_arr[6]	= dynamic_cast<ui::Button*>(FindControl(L"btn_blue"));
btn_arr[7]	= dynamic_cast<ui::Button*>(FindControl(L"btn_blue"));
btn_arr[8]	= dynamic_cast<ui::Button*>(FindControl(L"btn_blue"));
btn_arr[9]	= dynamic_cast<ui::Button*>(FindControl(L"btn_blue"));
btn_arr[10]	= dynamic_cast<ui::Button*>(FindControl(L"btn_blue"));
btn_arr[11]	= dynamic_cast<ui::Button*>(FindControl(L"btn_blue"));

long long end = std::chrono::system_clock::now().time_since_epoch().count();
std::wstring sss =fmt::format(L"{}", (end-start));
prichedit_show_->SetText(sss);

執行結果

時間單位: 微秒(microsecond)

序號 間隔(毫秒)
1 21
2 21
3 23
4 22
5 23
6 21
7 21
8 22
9 24
10 23

.......
大約執行時間為 22微妙 左右

優化後

ui::Button *btn_arr[12] = { nullptr };
long long start = std::chrono::system_clock::now().time_since_epoch().count();

find_control2(std::wstring(L"btn_blue"), btn_arr[0]);
find_control2(std::wstring(L"btn_blue"), btn_arr[1]);
find_control2(std::wstring(L"btn_blue"), btn_arr[2]);
find_control2(std::wstring(L"btn_blue"), btn_arr[3]);
find_control2(std::wstring(L"btn_blue"), btn_arr[4]);
find_control2(std::wstring(L"btn_blue"), btn_arr[5]);
find_control2(std::wstring(L"btn_blue"), btn_arr[6]);
find_control2(std::wstring(L"btn_blue"), btn_arr[7]);
find_control2(std::wstring(L"btn_blue"), btn_arr[8]);
find_control2(std::wstring(L"btn_blue"), btn_arr[9]);
find_control2(std::wstring(L"btn_blue"), btn_arr[10]);
find_control2(std::wstring(L"btn_blue"), btn_arr[11]);

long long end = std::chrono::system_clock::now().time_since_epoch().count();
std::wstring sss =fmt::format(L"{}", (end-start));
prichedit_show_->SetText(sss);

執行結果

時間單位: 微秒(microsecond)

序號 間隔(毫秒)
1 21
2 21
3 20
4 18
5 19
6 20
7 18
8 20
9 19
10 20

.......
大約執行時間為 19微妙 左右

時間分析

優化後,程式執行時間縮短了約 2~3 毫秒,但是程式碼量卻節省不少。 且易於維護。好處多多。

結論

  • for可以再一定程度上(實際為準)縮短執行時間
  • 儘量簡化程式碼,方便維護,縮短程式執行時間