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可以再一定程度上(实际为准)缩短执行时间
- 尽量简化代码,方便维护,缩短程序执行时间
继续优化
采用find_control2
方式,已经能明显看到效果了。但是,依然还会写很多重复代码,继续优化。
优化后
find_control3 函数
find_control3为优化后的函数,函数体如下:
template<typename T>
void find_control3(const std::wstring name_arr[], T** t)
{
// 控件name个数
unsigned int name_len = sizeof(name_arr) / sizeof(std::wstring);
// 控件个数
unsigned int t_len = sizeof(t) / sizeof(T);
if (0 == name_len || 0 == t_len)
return;
// 避免越界
unsigned int min_len = (name_len > t_len) ? t_len : name_len;
for (unsigned int index = 0; index < min_len; ++index)
{
find_control2(name_arr[index], t[index]);
}
}
find_control3
需要结合find_control2
使用
调用方式如下
ui::Button *btn_arr[12] = { nullptr };
std::wstring name_arr2[] =
{
L"btn_blue",
L"btn_blue",
L"btn_blue",
L"btn_blue",
L"btn_blue",
L"btn_blue",
L"btn_blue",
L"btn_blue",
L"btn_blue",
L"btn_blue",
L"btn_blue",
L"btn_blue"
};
find_control3(name_arr2, btn_arr);
执行结果
时间单位: 微秒(microsecond)
序号 | 间隔(微秒) |
---|---|
1 | 2 |
2 | 2 |
3 | 2 |
4 | 2 |
5 | 2 |
6 | 2 |
7 | 2 |
8 | 2 |
9 | 2 |
10 | 2 |
....... | |
大约执行时间为 2微妙 左右. |
哇瑟, 这差太多了,执行时间瞬间又2位数将为个位数,且为2微秒。 最终的改进结果:
case | decrease |
---|---|
相对for | 75% |
相对使用索引 | 95% |
结论
- 模板是个好东西,不知道你用了多少
- 代码优化,极为重要
C++代码优化之nim_duilib控件关联的更多相关文章
- nim_duilib(18)之xml控件关联优化
方法1 直接调用函数FindControl函数,返回Control*类型,对返回的类型强制转换 ui::CheckBox* pcheckbox = (ui::CheckBox*)(FindContro ...
- MFC 如何为控件关联变量
所关联的变量常见有两种,一种就是控件变量,一种就是数字变量. 为控件关联变量的方法也有两种,一种是通过软件工具添加,一种是手动添加代码. 软件工具添加,方便简单,但是根据软件的版本不同,以及不同的空间 ...
- MFC 可编辑文本框,MFC控件关联变量总结
Edit Control控件,默认状态下,按回车会调用OnOK()关闭窗体.解决此bug可以,类视图中单击CMFCApplication3Dlg,下方重写OnOK(),注释掉其中的代码即可. Edit ...
- Binding(二):控件关联和代码提升
上节我们讲到,使用Binding,我们可以关联后台代码中的属性,在某些情况下,我们可能需要将两个控件关联起来,借助Binding,我们也可以轻松的实现. 关联控件 设想这样一个场景,界面中有个Chec ...
- LODOP打印控件关联输出各内容
Lodop打印控件利用SET_PRINT_STYLEA里面的“LinkedItem”可以把多个独立的内容关联起来,让它们顺序打印.这样,就可以实现很多效果,例如一些内容紧跟着表格下方输出,关联表格后就 ...
- iOS-UI-UI控件概述
以下列举一些在开发中可能用得上的UI控件: IBAction和IBOutlet,UIView 1 @interface ViewController : UIViewController 2 3 @p ...
- 背水一战 Windows 10 (31) - 控件(按钮类): ButtonBase, Button, HyperlinkButton, RepeatButton, ToggleButton, AppBarButton, AppBarToggleButton
[源码下载] 背水一战 Windows 10 (31) - 控件(按钮类): ButtonBase, Button, HyperlinkButton, RepeatButton, ToggleButt ...
- 控件(按钮类): ButtonBase, Button, HyperlinkButton, RepeatButton, ToggleButton, AppBarButton, AppBarToggleButton
介绍背水一战 Windows 10 之 控件(按钮类) ButtonBase Button HyperlinkButton RepeatButton ToggleButton AppBarButton ...
- [深入浅出Windows 10]QuickCharts图表控件库解析
13.4 QuickCharts图表控件库解析 QuickCharts图表控件是Amcharts公司提供的一个开源的图表控件库,这个控件库支持WPF.Silverlight.和Windows等 ...
随机推荐
- Small but Funny Tricks [Remember them all!]
模数 1e9 的神奇求行列式: #include <bits/stdc++.h> using namespace std; const int maxn = 1e2, mod = 1e9; ...
- Nginx+uwsgi+django+vue部署项目
购买服务器 # 购买阿里云服务器 # 短期或是测试使用,创建 按量收费 服务器,可以随时删除,删除后不再计费,但要保证账户余额100元以上 连接服务器 1)账号 >: ssh root@39.9 ...
- git创建项目,代码仓库
1.首先在服务端远程创建仓库 mkdir project.git cd project.git git --bare init 2.在本地创建项目推送到远程服务端仓库 mkdir myproj ...
- 简单mvc框架核心笔记
简单mvc框架核心笔记 看了thinkphp5的源码,模仿写了一个简单的框架,有一些心得笔记,记录一下 1.目录结构 比较简单,没有tp那么复杂,只是把需要的核心类写了一些. 核心类库放在mykj里, ...
- 详解工作流框架Activiti的服务架构和组件
摘要:通过这篇文章,可以对工作流有一个基本的认识,为后续工作流框架Activiti的学习打下坚实的基础. 本文分享自华为云社区<BPMN工作流的基本概念!详解工作流框架Activiti的服务架构 ...
- 巩固javaweb的第三十一天
巩固内容 变量的作用范围 如果要访问的信息在 pageScope.requestScope.sessionScope 和 applicationScope 中存储, 则使用表达式语言访问的时候可以直接 ...
- Java【常用的日期操作】
目录 1.设置时间 2.获取年月日时分秒 3.通过运算获取时间 4.和Date类转换 5.格式化时间 6.新功能LocalDate:当前日期格式化 7.示例 java.util.Calendar 类是 ...
- 使用Rapidxml重建xml树
需求 : 重建一棵xml树, 在重建过程中对原来的标签进行一定的修改. 具体修改部分就不给出了, 这里只提供重建部分的代码 code : /****************************** ...
- OpenStack之七: compute服务(端口8774)
注意此处的bug,参考o版 官网地址 https://docs.openstack.org/nova/stein/install/controller-install-rdo.html 控制端配置 # ...
- HUD总结
HUD 指示器/HUD/遮盖/蒙板 半透明的指示器如何实现 指示器的alpha = 1.0; 指示器的背景色是半透明的 1. 创建颜色 直接创建对应的颜色 + (UIColor *)blackColo ...