前言

  • 使用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控件关联的更多相关文章

  1. nim_duilib(18)之xml控件关联优化

    方法1 直接调用函数FindControl函数,返回Control*类型,对返回的类型强制转换 ui::CheckBox* pcheckbox = (ui::CheckBox*)(FindContro ...

  2. MFC 如何为控件关联变量

    所关联的变量常见有两种,一种就是控件变量,一种就是数字变量. 为控件关联变量的方法也有两种,一种是通过软件工具添加,一种是手动添加代码. 软件工具添加,方便简单,但是根据软件的版本不同,以及不同的空间 ...

  3. MFC 可编辑文本框,MFC控件关联变量总结

    Edit Control控件,默认状态下,按回车会调用OnOK()关闭窗体.解决此bug可以,类视图中单击CMFCApplication3Dlg,下方重写OnOK(),注释掉其中的代码即可. Edit ...

  4. Binding(二):控件关联和代码提升

    上节我们讲到,使用Binding,我们可以关联后台代码中的属性,在某些情况下,我们可能需要将两个控件关联起来,借助Binding,我们也可以轻松的实现. 关联控件 设想这样一个场景,界面中有个Chec ...

  5. LODOP打印控件关联输出各内容

    Lodop打印控件利用SET_PRINT_STYLEA里面的“LinkedItem”可以把多个独立的内容关联起来,让它们顺序打印.这样,就可以实现很多效果,例如一些内容紧跟着表格下方输出,关联表格后就 ...

  6. iOS-UI-UI控件概述

    以下列举一些在开发中可能用得上的UI控件: IBAction和IBOutlet,UIView 1 @interface ViewController : UIViewController 2 3 @p ...

  7. 背水一战 Windows 10 (31) - 控件(按钮类): ButtonBase, Button, HyperlinkButton, RepeatButton, ToggleButton, AppBarButton, AppBarToggleButton

    [源码下载] 背水一战 Windows 10 (31) - 控件(按钮类): ButtonBase, Button, HyperlinkButton, RepeatButton, ToggleButt ...

  8. 控件(按钮类): ButtonBase, Button, HyperlinkButton, RepeatButton, ToggleButton, AppBarButton, AppBarToggleButton

    介绍背水一战 Windows 10 之 控件(按钮类) ButtonBase Button HyperlinkButton RepeatButton ToggleButton AppBarButton ...

  9. [深入浅出Windows 10]QuickCharts图表控件库解析

    13.4 QuickCharts图表控件库解析     QuickCharts图表控件是Amcharts公司提供的一个开源的图表控件库,这个控件库支持WPF.Silverlight.和Windows等 ...

随机推荐

  1. linux—查看所有的账号以及管理账号

    用过Linux系统的人都知道,Linux系统查看用户不是会Windows那样,鼠标右键看我的电脑属性,然后看计算机用户和组即可. 那么Linux操作系统里查看所有用户该怎么办呢?用命令.其实用命令就能 ...

  2. Python中类的各式方法介绍

    本文类的方法介绍包括类方法.属性方法.静态方法.修改属性方法等内置装饰器装饰的方法,以及类的一些特殊成员方法 1. 类的特殊成员方法 1.1 构造方法 # -*- coding:utf-8 -*- # ...

  3. Python os模块与sys模块

    1.os模块简单使用及说明 # -*- coding:utf-8 -*- """ os模块主要用于系统,处理程序与系统交互问题 大部分如属性等功能在linux系统中会使用 ...

  4. Shell 指定行处理head、tail、sed

    目录 Shell 指定行处理 head.tail.sed head 前几行 tail sed 删除.替换.新增.选取 案例 删除行 插入行 查看某行 替换某行 部分数据的查找并替换 读写操作 Shel ...

  5. [php安全]原生类的利用

    php原生类的利用 查看原生类中具有魔法函数的类 $classes = get_declared_classes(); foreach ($classes as $class) { $methods ...

  6. IPv6 私有地址

    在互联网的地址架构中,专用网络是指遵守RFC 1918(IPV4)和RFC 4193(IPV6)规范,使用专用IP地址空间的网络.私有IP无法直接连接互联网,需要使用网络地址转换(Network Ad ...

  7. 【bfs】洛谷 P1443 马的遍历

    题目:P1443 马的遍历 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 记录一下第一道ac的bfs,原理是利用队列queue记录下一层的所有点,然后一层一层遍历: 其中: 1.p ...

  8. 【Git项目管理】Git分支 - 远程分支

    远程分支 远程引用是对远程仓库的引用(指针),包括分支.标签等等. 你可以通过 git ls-remote (remote) 来显式地获得远程引用的完整列表,或者通过 git remote show ...

  9. spring cloud config center Git SSH configuration

    Git SSH configuration using properties By default, the JGit library used by Spring Cloud Config Serv ...

  10. C# 使用modbus 读取PLC 寄存器地址

    使用的组件Nmodbus 定义参数,全局变量: //创建modbus实体对象 private static ModbusFactory modbusFactory; private static IM ...