多重 for 循环,如何提高效率?

2258 字 14 图 : 文章字数

6 分钟 : 预计阅读

网络 : 内容来源

BabyCoder : 编辑整理


前言

  我在《华为 C 语言编程规范》中看到了这个:当使用多重循环时,应该将最忙的循环放在最内层。如下图:

  由上述很简单的伪代码可以看到,推荐使用的方式是:外小内大的方式。也就是内层循环是最忙的。

  然后我又在另外一份编程规范手册中,看到了类似的要求,如下图:

  看到了这个小技巧之后,我迫不及待的分享给我的小伙伴,后来闲下来的时候,就想自己做个测试,验证一下是否真的是这样。

Ubuntu 测试

  使用 Ubuntu 14.04 的系统进行测试,基本信息如下:

  • 系统版本:Ubuntu14.04

  • gcc 版本:4.8.2

  我使用了两份不同的代码文件进行测试,第一份是 外大内小 的代码,如下:

#include <iostream>#include <stdio.h>#include <stdlib.h>#include <sys/time.h>#include <unistd.h>
using namespace std;
int main(){  struct timeval tv;  unsigned long ulStartTime, ulEndTime;gettimeofday(&tv, NULL);                               // 获取当前时间  ulStartTime = tv.tv_sec * 1000000 + tv.tv_usec;        // 计算当前起始时间  cout << "start time = " << ulStartTime << endl;        // 打印显示  for(unsigned int i = 0; i < 1000000; i++)              // 测试代码  {    for(int j = 0; j < 100; j++)    {          }  }  gettimeofday(&tv, NULL);  ulEndTime = tv.tv_sec * 1000000 + tv.tv_usec;          // 计算结束时间  cout << "end time = " << ulEndTime << endl;            // 打印结束时间  cout << "Time = " << ulEndTime - ulStartTime << endl;  // 计算时间差值 微秒 us}

  执行上述代码,运行结果如下,耗时:165280us

  接着,我又准备了另外一份 外小内大 的代码,对比只是调换了 for 循环内外层的循环次数而已,如下:

#include <iostream>#include <stdio.h>#include <stdlib.h>#include <sys/time.h>#include <unistd.h>
using namespace std;
int main(){  struct timeval tv;  unsigned long ulStartTime, ulEndTime;gettimeofday(&tv, NULL);  ulStartTime = tv.tv_sec * 1000000 + tv.tv_usec;  cout << "start time = " << ulStartTime << endl;  for(int i = 0; i < 100; i++)  {    for(unsigned int j = 0; j < 1000000; j++)    {}  }  gettimeofday(&tv, NULL);  ulEndTime = tv.tv_sec * 1000000 + tv.tv_usec;  cout << "end time = " << ulEndTime << endl;  cout << "Time = " << ulEndTime - ulStartTime << endl;}

  上述代码的执行结果如下,耗时:155960us

  对比上述两份代码的运行结果,可以很明显的看到,外小内大效率更高一点!

  不过,你以为这就结束了吗?

树莓派测试

  手边刚好有一台树莓派,前段时间刚安装了最新的官方系统,就想着拿来做一下测试,基本信息如下:

  • 树莓派系统版本:buster

  • g++ 版本:8.3.0

  测试代码与在 Ubuntu 上运行的代码保持一致,这里就不重复贴代码了,只看一下运行结果。

  下边这个是 外大内小 的,运行结果如下,耗时:1214569us

  这个是 外小内大 的,运行结果如下,耗时:1345193us

  完了,可以很明显的看到,外大内小 的运行效率要更高一点。

问题分析

  我也是有点蒙逼的,不知道为啥会出现截然相反的情况,对比两个系统版本,硬件设备来看,推测原因有如下几种可能:

  • 处理器架构不同

    • Ubuntu 是安装在 win10 台式机上的虚拟机中,所使用的硬件应该为台式机的硬件(处理器等);而台式机的硬件是英特尔的 X86 架构的处理器。

    • 树莓派使用的硬件平台,是一个 ARM 架构的芯片,具体可以参考图片:

图片来源:树莓派实验室
  • gcc 版本不同,在刚开始操作的时候,也详细的列出了当前程序使用的环境

    • Ubuntu14.04 中 gcc  版本为:4.8.2

    • 树莓派中 gcc 版本为:8.3.0

  目前能想到的差异就这么多,其他的暂时还不知道,难道这个就是运行在 X86 平台和 ARM 平台的区别之一?更多的更深入的研究还有待后续学习研究才能知道。今天的讨论就到这里为止吧!

总结

  1. 在 X86 架构平台下,外小内大效率较高;

  2. 由于参考的规范手册,可能是用于服务器开发,而服务器仍然是 X86 架构的处理器居多,因此 for 循环的多重循环规则较适用;

  3. 需要考虑在嵌入式等 ARM 平台下,此规则是否同样适用,是否还有其他应用场景限制等?欢迎私信/加我好友一起讨论~

推荐阅读:

专辑|Linux文章汇总

专辑|程序人生

专辑|C语言

我的知识小密圈

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/466768.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【转】Web服务软件工厂

patterns & practices开发中心 摘要 Web服务软件工厂(英文为Web Service Software Factory&#xff0c;也称作服务工厂)是一个集成的工具、模式、源代码和规范性指导的集合。它的设计是为了帮助你迅速、一致地构建符合普遍的体系结构和设计模式的Web服务。 如果你是一名负责…

java gui 连接mysql数据库

package com.wt010.db;import java.sql.*;import javax.swing.JFrame; import javax.swing.JTextArea;public class MySQLUtil extends JFrame {// JDBC 驱动名及数据库 URLstatic final String JDBC_DRIVER "com.mysql.jdbc.Driver"; static final String DB_URL …

单片机外围模块漫谈之二,如何提高ADC转换精度

在此我们简要总结一下ADC的各种指标如何理解&#xff0c;以及从硬件到软件都有哪些可以采用的手段来提高ADC的转换精度。1.ADC指标除了分辨率&#xff0c;速度&#xff0c;输入范围这些基本指标外&#xff0c;衡量一个ADC好坏通常会用到以下这些指标&#xff1a;失调误差,增益误…

Datawhale-零基础入门NLP-新闻文本分类Task05

该任务是用Word2Vec进行预处理&#xff0c;然后用TextCNN和TextRNN进行分类。TextCNN是利用卷积神经网络进行文本文类&#xff0c;TextCNN是用循环神经网络进行文本分类。 1.Word2Vec 文本是一类非结构化数据&#xff0c;文本表示模型有词袋模型&#xff08;Bag of Words&…

如何把握网络工程师的“钱”途,专访文字。

前两天接受了IT168的视频专访&#xff0c;这里把专访的内容发布出来&#xff0c;大家可以借鉴一下。主持人&#xff1a;大家上午好&#xff0c;欢迎收看IT168网络频道的网上直播节目。我们今天上午的此次直播的主题是网络工程师:如何掌握你的“钱”途&#xff1f;众所周知&…

想要学好C++有哪些技巧?

学C能干什么&#xff1f; 往细了说&#xff0c;后端、客户端、游戏引擎开发以及人工智能领域都需要它。往大了说&#xff0c;构成一个工程师核心能力的东西&#xff0c;都在C里。跟面向对象型的语言相比&#xff0c;C是一门非常考验技术想象力的编程语言&#xff0c;因此学习起…

window.open打开新窗口被浏览器拦截的处理方法

一般我们在打开页面的时候&#xff0c; 最常用的就是用<a>标签&#xff0c;如果是新窗口打开就价格target"_blank"属性就可以了&#xff0c; 如果只是刷新当前页面就用window.location.reload()&#xff0c; 在某些特殊情况下也要用到另外一种新窗口打开的方法…

Datawhale-零基础入门NLP-新闻文本分类Task06

之前已经用RNN和CNN进行文本分类&#xff0c;随着NLP的热门&#xff0c;又出现了大热的Attention&#xff0c;Bert&#xff0c;GPT等模型&#xff0c;接下来&#xff0c;就从理论进行相关学习吧。接下来&#xff0c;我们会经常听到“下游任务”等名词&#xff0c;下游任务就是N…

服务器响应HTTP的类型ContentType大全

ContentType 属性指定服务器响应的 HTTP 内容类型。如果未指定 ContentType&#xff0c;默认为 text/html。在ASP中使用它&#xff1a; <% Response.ContentType "text/HTML" %> <% Response.ContentType "image/GIF" %> <% Response.Con…

Linux文件系统及属性

Linux文件系统及属性 宗旨&#xff1a;技术的学习是有限的&#xff0c;分享的精神是无限的。 一、Linux系统下文件类型及属性 1、inode结构 /*索引节点对象由inode结构体表示&#xff0c;定义文件在linux/fs.h中*/ struct inode {struct hlist_node i_hash; …

Linux-C编程 / 多线程 / 如何终止某个线程?

示例 demo最简单的 demo&#xff1a;static void* thread1_func(void *arg) {int i 0;// able to be cancelpthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);for(i0; ; i) {printf("thread1 %d\n", i);…

PaddlePaddle入门——基本概念

最近报了百度的深度学习认证&#xff0c;需要使用Paddle进行编程实现&#xff0c;找了一些基础教程&#xff0c;特意记录下来&#xff0c;加深印象。思维导图如下&#xff1a; 一、Paddle的内部执行流程 二、内部详解 1.Variable&#xff08;变量&#xff09; &#xff08;1…

我会在天堂爱你.

★☆你相信爱情吗&#xff1f;☆★如果你觉得这篇文章很好的话&#xff01;那么请把这篇信息传给20位网友或以上&#xff0c;那天下的有情人也会终成眷属&#xff0c;当然也包括你自己&#xff01;....世界消失了&#xff0c;我会在天堂爱你.如果你走了&#xff0c;我会在泪水中…

Linux C语言实现ls -l

Linux下C语言实现ls -l功能 宗旨&#xff1a;技术的学习是有限的&#xff0c;分享的精神是无限的。 需求&#xff1a;用ls -l显示文件夹下所有的文件及属性 分析&#xff1a;1 用ls显示文件夹下的所有文件&#xff0c;首先用opendir打开文件夹&#xff0c;再用readdir读取…

回答一个微信好友的创业问题

ps:很喜欢这种有烟火气息的照片— — 提问&#xff1a;我最近要创业&#xff0c;打算跟一个朋友合伙&#xff0c;但是我朋友不会技术&#xff0c;所以他只投入钱&#xff0c;也不会参与公司的管理。我们启动资金是10万&#xff0c;他打算投入7万&#xff0c;想占股65%。因为没有…

百度深度学习初级认证——已过

开头先放图&#xff0c;百度深度学习初级工程师认证已通过&#xff0c;记录一下备战和考试细节&#xff01;&#xff01;&#xff01; 1.报考 当时是通过百度的AI Studio看到深度学习的认证了&#xff0c;价格是800&#xff0c;然后阴差阳错从百度技术学院的链接看到深度学习…

Windows Mobile开发资源相关下载收录

最近收集了些关于Windows Mobile开发必备工具。以下资源完全是自己下载过的&#xff0c;直接从迅雷下载页面拷贝过来的地址。链接应该没问题的。 Windows Mobile 6 Professional SDK Refresh.msihttp://www.microsoft.com/downloads/info.aspx?na46&p1&SrcDisplayLang…

数值计算(Python实现)(一)

数值计算&#xff08;Python实现&#xff09;&#xff08;一&#xff09; 本篇内容简介&#xff1a; 解线性方程组&#xff1a;高斯消元法和高斯列主元消去法解线性方程组的迭代方法&#xff1a;雅克比&#xff08;Jacobi&#xff09;迭代法与高斯&#xff0d;赛德尔迭代法拉格…

哦,这是桶排序

漫画&#xff1a;什么是桶排序&#xff1f;要了解桶排序之前&#xff0c;可以先看看上面小灰的那篇文章&#xff0c;我觉得是比较不错的。桶排序也可以理解为分类排序&#xff0c;把不同的数据归类&#xff0c;归类之后再重新排序&#xff0c;每个桶里面的内容就是一类数据&…

LinuxC高级编程——进程

LinuxC高级编程——进程 宗旨&#xff1a;技术的学习是有限的&#xff0c;分享的精神是无限的。 每个进程在内核中都有一个进程控制块&#xff08; PCB&#xff09;来维护进程相关的信息&#xff0c; Linux内核的 进程控制块是task_struct结构体。PCB包含的信息&#xff1a; …