【程序语言】程序循环的那些事儿

2024-03-29 00:18

本文主要是介绍【程序语言】程序循环的那些事儿,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

   我一直认为循环是程序的发动机,所以决定深入探究一下循环的那些事儿!

   下面我们研究一下循环的写法和效率:

   背景是这假设有一个存放20个元素的数组int arr[20],我们想对它进行求和,也就arr[0]+arr[1]+…… 好的,在这个简单的背景下,我们开始我们的探索吧!

 

  1.第一个富有建设性的版本诞生了,她是那么的直观,那么的整洁,嘻嘻:   

     int sum = 0;
sum =  arr[0]  +arr[1]  +arr[2]  +arr[3]
+arr[4]  +arr[5]  +arr[6]  +arr[7]
+arr[8]  +arr[9]  +arr[10] +arr[11]
+arr[12] +arr[13] +arr[14] +arr[15]
+arr[16] +arr[17] +arr[18] +arr[19]; 

     也许你觉得最初级的程序员都不会写出这样的代码的,但请不要鄙视这种写法!真的,也许某一天你会喜欢上这个版本的!

  2.第二个版本是百分之80的程序员都会这么写的一种最普通的写法:

     int sum=0;
for(int i=0; i<20; i++)
{    sum += arr[j];    }

 这个版本是不是忒熟悉,忒顺眼,忒良好,忒精简。嘿嘿,也忒普通!

  3.第三个版本来自第二个版本的改良。什么?第二个还可以改良,骗人吧!没骗你:   

    int sum=0;
for(int i=0; i<20; ++i)
{    sum += arr[i];    }

     神啊,请问这也叫改良吗?几乎没动过嘛!错,i++改成了++i。这也叫改良吗? 当然算改良,要不,你自己测测效率就知道了。

 

  4.第四个版本来自C++版本的指针,其他语言不用担心,其实语言编译器也用指针的,嘿嘿。

     int sum=0;
for(int i=0; i<20; ++i)
{   sum += *(arr+i);  }

     用指针有什么好的?因为 arr[i] 会被翻译成 *( arr + i*sizeof(int) ) ,有差别吗?当然有啦。但是这是在古老的编译器中,现代流行的编译器中,其实有优化过了,arr[i]和*    (arr+i)基本没区别了!

 

   5.最后的一个版本来自元编程(metaprogramming),编译型语言在理论上支持元编程。现在貌似Ruby也支持元编程,但这里还是以C++为例子好了,大家熟悉点儿嘛。

     template <int Dim,typename T>
struct Sum{
static T sum(T *arr){
return (*arr) + Sum<Dim-1,T>::sum(arr+1);
};
};
template<typename T>
struct Sum<1,T>{
static T sum(T *arr){
return *arr;
};
};
int sum = Sum<20,int>::sum(arr);

 你骗人这算什么熟悉!!!呵呵,有不熟悉,才有熟悉嘛!这是一种挖掘编译器潜力的编程方法,是一种用来生成代码的编程方式。例如这个版本的求和,你不要以为她调用了任何函数,其实她和第一个版本是一摸一样的,编译器会自动将代码展开到第一个版本的形式。

    现在,是时候看看这五个版本的循环有什么区别了。为保证公平,我对每段代码都循环执行1,000,000,000次,下面就是我们期待良久的结果了:

                   第一次     第二次     第三次    第四次

      版本1:0              0              0            0

      版本2:8290        8180        8200      8250

      版本3:8090        8160        8070      8234

      版本4:8252        8140        8050      8460

      版本5:10            0              0            0

   嘻嘻,看结果什么感觉,说过不要轻视第一个版本吧,你真有可能什么时候需要她呢!i++和++i还是有区别的哦!至少我测试了很多次,一直都是++i快那么一点儿,虽然不多。第5个元编程版本什么感受呢?

 

 结论:

   1.不要轻视那些最直观的傻瓜式编程,或许计算机本身最擅长的就是这个!

   2.i++和++i还是有区别的,有兴趣可以看看左值和右值的区别,另外i++和i++还涉及到一个中间变量问题。

   3.在现代C++中还是少使用指针运算了。多态和智能指针sharedptr除外!

   4.元编程是生成代码的编程,可能在需要极致效率的时候,而程序中存在常量的时候,元编程是个选择。

 

说明一下“开发效率”和“执行效率”的均衡:

   1.一个程序员 一年的 工资 按中国的平均年薪算 6W.

   2.一台服务器按一般的配置算1W

现在需要写一个程序:假设有两个实现版本,四家公司用。

   1.X版本注重开发效率,需要    2  个月 5   人团队完成.

   2.Y版本注重执行效率,需要 10  个月 25 人团队完成.

   3.A公司是一家小公司,需要程序运行在    2              台服务器上,服务于2,000               人左右.

   4.B公司是一家小公司,需要程序运行在   10             台服务器上,服务于10,000             人左右.

   5.C公司是一家大公司,需要程序运行在   10,000      台服务器上,服务于10,000,000      人左右.

   6.D公司是一家大公司,需要程序运行在   1,000,000 台服务器上,服务于1,000,000,000 人左右.

其实,对程序成本进行简略计算,程序员加管理成本,简单计算为12W每年每人。X版本程序成本10W,

Y版本程序成本250W。假设 Y 比 X 效率高 5%, 那么就会节省 5%的服务器,

   1.对 A 公司而言,节省了 0.1       台服务器,如果使用 Y 版本,亏损    239.9W.

   2.对 B 公司而言,节省了 0.5       台服务器,如果使用 Y 版本,亏损    239.5W.

   3.对 C 公司而言,节省了 500      台服务器,如果使用 Y 版本,净赚    260.0W.

   4.对 D 公司而言,节省了 10,000 台服务器,如果使用 Y 版本,净赚 9,760.0W.

这就是一种衡量,小公司要的是开发效率,恨不得所有东西都可以用Ruby写,大公司要的是效率,恨不得

“所有程序都可以用汇编写!”. 

 

这篇关于【程序语言】程序循环的那些事儿的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/857096

相关文章

MySQL存储过程之循环遍历查询的结果集详解

《MySQL存储过程之循环遍历查询的结果集详解》:本文主要介绍MySQL存储过程之循环遍历查询的结果集,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言1. 表结构2. 存储过程3. 关于存储过程的SQL补充总结前言近来碰到这样一个问题:在生产上导入的数据发现

python编写朋克风格的天气查询程序

《python编写朋克风格的天气查询程序》这篇文章主要为大家详细介绍了一个基于Python的桌面应用程序,使用了tkinter库来创建图形用户界面并通过requests库调用Open-MeteoAPI... 目录工具介绍工具使用说明python脚本内容如何运行脚本工具介绍这个天气查询工具是一个基于 Pyt

Ubuntu设置程序开机自启动的操作步骤

《Ubuntu设置程序开机自启动的操作步骤》在部署程序到边缘端时,我们总希望可以通电即启动我们写好的程序,本篇博客用以记录如何在ubuntu开机执行某条命令或者某个可执行程序,需要的朋友可以参考下... 目录1、概述2、图形界面设置3、设置为Systemd服务1、概述测试环境:Ubuntu22.04 带图

Python程序打包exe,单文件和多文件方式

《Python程序打包exe,单文件和多文件方式》:本文主要介绍Python程序打包exe,单文件和多文件方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录python 脚本打成exe文件安装Pyinstaller准备一个ico图标打包方式一(适用于文件较少的程

Python程序的文件头部声明小结

《Python程序的文件头部声明小结》在Python文件的顶部声明编码通常是必须的,尤其是在处理非ASCII字符时,下面就来介绍一下两种头部文件声明,具有一定的参考价值,感兴趣的可以了解一下... 目录一、# coding=utf-8二、#!/usr/bin/env python三、运行Python程序四、

无法启动此程序因为计算机丢失api-ms-win-core-path-l1-1-0.dll修复方案

《无法启动此程序因为计算机丢失api-ms-win-core-path-l1-1-0.dll修复方案》:本文主要介绍了无法启动此程序,详细内容请阅读本文,希望能对你有所帮助... 在计算机使用过程中,我们经常会遇到一些错误提示,其中之一就是"api-ms-win-core-path-l1-1-0.dll丢失

SpringBoot后端实现小程序微信登录功能实现

《SpringBoot后端实现小程序微信登录功能实现》微信小程序登录是开发者通过微信提供的身份验证机制,获取用户唯一标识(openid)和会话密钥(session_key)的过程,这篇文章给大家介绍S... 目录SpringBoot实现微信小程序登录简介SpringBoot后端实现微信登录SpringBoo

uniapp小程序中实现无缝衔接滚动效果代码示例

《uniapp小程序中实现无缝衔接滚动效果代码示例》:本文主要介绍uniapp小程序中实现无缝衔接滚动效果的相关资料,该方法可以实现滚动内容中字的不同的颜色更改,并且可以根据需要进行艺术化更改和自... 组件滚动通知只能实现简单的滚动效果,不能实现滚动内容中的字进行不同颜色的更改,下面实现一个无缝衔接的滚动

Nginx部署React项目时重定向循环问题的解决方案

《Nginx部署React项目时重定向循环问题的解决方案》Nginx在处理React项目请求时出现重定向循环,通常是由于`try_files`配置错误或`root`路径配置不当导致的,本文给大家详细介... 目录问题原因1. try_files 配置错误2. root 路径错误解决方法1. 检查 try_f

Java使用WebView实现桌面程序的技术指南

《Java使用WebView实现桌面程序的技术指南》在现代软件开发中,许多应用需要在桌面程序中嵌入Web页面,例如,你可能需要在Java桌面应用中嵌入一部分Web前端,或者加载一个HTML5界面以增强... 目录1、简述2、WebView 特点3、搭建 WebView 示例3.1 添加 JavaFX 依赖3