python循环性能pk

2023-05-16

python循环性能pk

在任何一种编程语言中,循环都是非常消耗时间的操作。假设任意一种简单的单步操作耗费的时间是1个单位,将此操作重复执行上万次,最终耗费的时间也将增长上万倍。众所周知,python不是一种执行效率较高的语言,因此,我们对于python语言里的循环性能更加关注。

forwhile

whilefor是python中常用的两种实现循环的方法,但它们的运行效率实际上是有差距的。使用下面的测试代码:

import timeit

def while_loop(n=100):
    i = 0
    s = 0
    while i < n:
        s += i
        i +=1
    return s


def for_loop(n=100):
    s = 0
    for i in range(n):
        s += i
    return s


def main():
    print('while loop:', timeit.timeit(while_loop, number=100))
    print('for loop:', timeit.timeit(for_loop, number=100))


if __name__ == '__main__':
    main()

运行结果:

# while loop: 0.11076588099240325
# for loop: 0.03892302500025835

可以看到:一个简单的求和的循环,for循环要比while循环快很多。

是什么导致这样的差距?

首先要说明的一点是:C代码效率优于python代码,这已经是常识。同时,Python 底层的解释器和内置函数是用 C 语言实现的

实际上,在每次循环中,while会比for多执行两步操作:边界检查和变量i的自增。即:while i < ni += 1,并且这两步都是显示的纯python脚本。相比之下,for循环不需要这两步额外的依赖于python脚本的操作,因此效率优于while循环,并且随着循环次数不断增加,二者的运行效率差距也越来越大。

为了证实以上的解释,我们做如下的试验:

import timeit


def while_loop(n=100):
    i = 0
    s = 0
    while i < n:
        s += i
        i += 1
    return s


def for_loop(n=100):
    s = 0
    for i in range(n):
        s += i
    return s


def for_loop_with_inc(n=100):
    s = 0
    for i in range(n):
        s += i
        i += 1
    return s


def for_loop_with_test(n=100):
    s = 0
    for i in range(n):
        if i < n:
            pass
        s += i
    return s


def main():
    print('while loop\t\t', timeit.timeit(while_loop, number=10000))
    print('for loop\t\t', timeit.timeit(for_loop, number=10000))
    print('for loop with increment\t\t',
          timeit.timeit(for_loop_with_inc, number=10000))
    print('for loop with test\t\t', timeit.timeit(for_loop_with_test, number=10000))


if __name__ == '__main__':
    main()

运行结果:

# while loop		 0.08734580200689379
# for loop		 0.039982129994314164
# for loop with increment		 0.04891946600400843
# for loop with test		 0.04814562000683509

可以看到,试验的结果证实了上面的结论。

内置函数

依然使用上面的例子,python里有一个内置的函数sum()可以求和,我们来对比下sum()和循环的效率。

import timeit


def while_loop(n=100):
    i = 0
    s = 0
    while i < n:
        s += i
        i += 1
    return s


def for_loop(n=100):
    s = 0
    for i in range(n):
        s += i
    return s


def sum_range(n=100):
    return sum(range(n))


def main():
    print('while loop\t\t', timeit.timeit(while_loop, number=10000))
    print('for loop\t\t', timeit.timeit(for_loop, number=10000))
    print('sum range\t\t', timeit.timeit(sum_range, number=10000))


if __name__ == '__main__':
    main()

运行结果:

# while loop		 0.052548438994563185
# for loop		 0.0333536260004621
# sum range		 0.00758898000640329

可以看到,sum()执行求和最快!这是因为sum()函数是内置函数,它是用c语言进行循环的,因此它比前面的whilefor效率更高。

继续优化

为了解决等差数列求和这个问题,我们除了粗暴循环还有什么好的方法吗?掌握基础的数学知识就可以知道: S u m ( A n ) = a 1 + a n 2 ∗ n Sum({A_n})=\frac{a_1 + a_n}{2}*n Sum(An)=2a1+ann.我们来测试一下直接计算的效率。

import timeit


def while_loop(n=100):
    i = 0
    s = 0
    while i < n:
        s += i
        i += 1
    return s


def for_loop(n=100):
    s = 0
    for i in range(n):
        s += i
    return s


def sum_range(n=100):
    return sum(range(n))


def math_sum(n=100):
    return (n * (n - 1)) // 2


def main():
    print('while loop\t\t', timeit.timeit(while_loop, number=10000))
    print('for loop\t\t', timeit.timeit(for_loop, number=10000))
    print('sum range\t\t', timeit.timeit(sum_range, number=10000))
    print('math sum\t\t', timeit.timeit(math_sum, number=10000))


if __name__ == '__main__':
    main()

运行结果:

# while loop		 0.060537102006492205
# for loop		 0.03300404299807269
# sum range		 0.007836175005650148
# math sum		 0.0013752939994446933

效率又提升了,原因很明显,我们只用一步操作就得到了结果,避免了成千上万次的循环(不管是python还是c),代码的效率自然达到了空前的提升。

最终结论

经过以上的测试,我们得到了最终的结论:实现循环的最快方式,就是不用循环。如果无法完全的避免循环,那么尽量使用python的内置函数,并且减少循环中的纯python脚本。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

python循环性能pk 的相关文章

随机推荐

  • nacos集群配置详解

    前导 xff1a 避免单点故障 xff0c nacos需采取集群模式 xff0c 且数据库也得换成高可用mysql数据库 xff08 自带的derby数据库很难做到集群配置的一致性 xff09 nacos切换mysql数据库 下载的naco
  • navicat创建连接 2002-can‘t connect to server on localhost(10061)且mysql服务已启动问题

    navicat创建连接 2002 can t connect to server on localhost xff08 10061 xff09 且mysql服务已启动问题 查看mysql是否启动查看本地mysql端口号 问题如上图 xff0
  • Navicat如何连接MySQL

    市面上有很多数据库连接工具 xff0c 比如Navicat SQLYog WorkBench等 xff0c 用的比较多的 xff0c 比较好用的 xff0c 还是Navicat 现在我们就来说说Navicat如何连接Mysql 此文仅适用于
  • Navicat报错:1045-Access denied for user root@localhost(using passwordYES)

    前言 xff1a 事情是这样的 xff0c 昨天我在调试导师给的一个oython的项目 xff0c 这个项目是没有文档的 xff0c 所以数据库那些信息我需要自己去匹配去创建 xff0c 于是我将这个项目连接到了我本地的数据库 xff0c
  • 「Spring Boot 系列」03. Spring Boot配置文件&yaml的基本语法

    Spring Boot的配置文件 配置文件分类yaml基本语法 1 概念 2 语法特点 3 数据类型 最后 Spring Boot 提供了大量的自动配置 xff0c 极大地简化了spring 应用的开发过程 xff0c 所以当你创建了一个
  • 「Spring Boot 系列」04. Spring Boot配置------获取数据

    Spring Boot数据获取 1 64 Value2 64 Environment3 64 ConfigurationProperties 简单来说 xff0c 数据获取就是从application yml配置文件中拿到相对应的值然后交给
  • 「Spring Boot 系列」08. Spring Boot整合MyBatis

    目录 Spring Boot整合MyBatis步骤 xff1a 1 新建Spring Boot工程 xff0c 并选择需要使用的技术集2 设置相关参数 xff08 数据源 xff09 3 编写一个实体类 Person java4 定义数据层
  • 「Spring Boot 系列」09. Spring Boot集成MyBatis-Plus实现CRUD

    目录 前言一 创建数据库 1 添加数据表2 填充数据表 二 整合MyBatis Plus 1 新建springboot工程2 导入对应的starter3 添加配置4 创建实体类5 定义数据层接口 xff0c 继承BaseMapper 三 C
  • centos7 yum安装jdk8

    1 安装之前先检查一下系统有没有自带open jdk 命令 xff1a rpm qa grep java rpm qa grep jdk rpm qa grep gcj 如果没有输入信息表示没有安装 2 首先检索包含java的列表 yum
  • 【2021最新版】RabbitMQ面试题总结(32道题含答案解析)

    文章目录 1 什么是rabbitmq xff1f 2 为什么要使用rabbitmq xff1f 3 使用rabbitmq的场景 4 如何确保消息正确地发送至RabbitMQ xff1f 如何确保消息接收方消费了消息 xff1f 5 如何避免
  • 忘记mysql密码后如何修改密码(2022最新版详细教程保姆级)

    忘记mysql密码后如何修改密码 注意事项步骤 注意事项 一共用到两个cmd窗口 xff0c 每一个都要以管理员身份打开 xff0c 且在修改密码后 xff0c 要先关闭第一个跳过验证密码的mysql服务的cmd窗口 xff0c 再启动my
  • 忘记密码时如何修改mysql密码

    前言 近期学习j2ee开发时 xff0c 初步接触MySQL xff0c 偶然发现以往安装MySQL时修改的密码忘记 xff0c 于是查找资料学习了如何在忘记密码的情况下改变MySQL密码 以下为末学个人简介 xff0c 有不周之处 xff
  • 快速入手node.js

    目录 1 什么是 Node js 2 fs模块 3 path模块 4 http 模块 1 IP 地址 2 域名和域名服务器 3 端口号 4 创建 web 服务器的基本步骤 1 什么是 Node js Node js是让Javascript脱
  • 快速掌握 MyBatis 框架(二)

    文章目录 一 前言 1 1 数据库与表1 2 实体类1 3 MyBatisX 插件1 4 SQL 日志查看配置 二 多表查询 2 1 一对一2 2 一对多 三 动态 SQL 使用 3 1 lt if gt 标签3 2 lt trim gt
  • Cesium加载离线地图和离线地形

    文章目录 前言一 Cesium加载离线地图 1 1 下载数据2 2 数据处理2 3 地图发布2 4下载速度改进 二 Cesium加载离线地形 2 1 下载数据2 2 数据处理2 3 地形发布2 4 遇到的问题 前言 直接把地图数据切片 xf
  • Charles抓包显示<unknown>解决方案

    上篇 xff1a Charles抓包微信小程序数据 charles抓包会出现 xff0c 请求前都加了锁 xff0c 具体地址为的情况 解决问题 首先电脑上需要安装charles xff0c 然后需要设置手机上的WiFi设置 xff0c 修
  • Chrome 配置samesite=none方式

    提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 文章目录 前言二 解决方案 1 方案一 xff1a 修改浏览器配置2 方案二 xff1a 使用Nginx3 方案三 xff1a 若服务器为
  • Chrome插件开发入门

    视频作者 xff1a 猿伙伴的个人空间 哔哩哔哩 bilibili 源码 xff1a https pan baidu com s 1EUOUo6QwHezyddmslyFsJQ 提取码 xff1a xtex 目录 一 第一个插件helloW
  • CISP-PTE真题演示

    周末帮好兄弟做PTE的真题 xff0c 觉得确实挺有意思的 xff0c 于是就有了这篇文章 xff0c 侵删侵删哈 第一阶段 基础题目一 xff1a SQL注入 所谓SQL注入 xff0c 就是通过把SQL命令插入到Web表单提交或输入域名
  • python循环性能pk

    python循环性能pk 在任何一种编程语言中 xff0c 循环都是非常消耗时间的操作 假设任意一种简单的单步操作耗费的时间是1个单位 xff0c 将此操作重复执行上万次 xff0c 最终耗费的时间也将增长上万倍 众所周知 xff0c py