前言

  • 使用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. 【机器学习与R语言】8- 神经网络

    目录 1.理解神经网络 1)基本概念 2)激活函数 3)网络拓扑 4)训练算法 2.神经网络应用示例 1)收集数据 2)探索和准备数据 3)训练数据 4)评估模型 5)提高性能 1.理解神经网络 1) ...

  2. Linux Alpine安装 Nginx

    Linux Alpine安装 Nginx 安装需要编译Nginx的扩展 apk add wget gcc g++ make 安装Nginx URL重定向,正则表达式模块pcre Pcre 源码下载地址 ...

  3. Python爬虫3大解析库使用导航

    1. Xpath解析库 2. BeautifulSoup解析库 3. PyQuery解析库

  4. git的使用理解(分支合并的使用理解,多人编程的解决方案)

    本文主要记录了对git日常使用的一些理解,主要是对git分支的一些感悟. git强大的版本控制系统,之前也使用过SVN,感觉上git对于多人开发的版本控制更加强大,特别是最近对git分支的使用,更是深 ...

  5. LeetCode 第一题 两数之和

    题目描述 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,你不能重复利用这个数组 ...

  6. 2019java面试

    1.面向对象的特征有哪些方面?答:面向对象的特征主要有以下几个方面:    抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面.抽象只关注对象有哪些属性和行为,并不关注 ...

  7. 理解ASP.NET Core - 模型绑定&验证(Model Binding and Validation)

    注:本文隶属于<理解ASP.NET Core>系列文章,请查看置顶博客或点击此处查看全文目录 模型绑定 什么是模型绑定?简单说就是将HTTP请求参数绑定到程序方法入参上,该变量可以是简单类 ...

  8. 使用cookie记录用户上次访问网页的时间,并返回到页面

    package com.hopetesting.cookie;import javax.servlet.ServletException;import javax.servlet.annotation ...

  9. matplotlib 坐标轴刻度能见度问题

    matplotlib 画图时如果图像太大就会挡住了坐标轴,刻度就看不到了.可以利用zorder设置level,level越小越先绘制. 例子: 1 import matplotlib.pyplot a ...

  10. shell脚本 监控网卡信息

    一.简介 源码地址 日期:2018/6/22 介绍:显示实时输入输出流量 效果图: 二.使用 适用:centos6+ 语言:英文 注意:无 下载 wget https://raw.githubuser ...