【Python性能优化】list、array与set

list、array与set

  • 详述
  • 测试代码

 
 
 
 
 
 
 
 

详述


本文对比 list 与 set 在插入和取值时的性能差异,以提供一条什么时候该选择什么数据类型的建议。先上结果:

array 与 list 的不同:

  • 内存方面
    • array 是 C array 的包装,它直接存储数据,占用的内存大小 = 元素个数 * 元素类型
    • list 是 Python Object,其中存储的每个数据都会被包装成 Python Object,所以内存占用大的多
  • 数据类型方面
    • array 只能存储相同数据类型
    • list 可以存储不同数据类型
  • 操作时间
    • list 因为存储的就是 PyObject,所以进行各类处理不需要频繁的进行数据转换
    • array 存储原始的 C 数据,所以和其他 Python 数据进行操作时,每次都要进行类型转换

 
选择 list 的场景

  1. 需要数据是有序的
  2. 需要存储可变变量(列表、字典)的
  3. 数据中可能会有重复的

 
选择 set 的场景

  1. 当需要频繁判断数据存在性,时间复杂度为 O(1),list 和 array 均为 O(N),但是 array 比 list 慢的多,因为每次判断都要对 array 中的元素进行 PyObject 和原始数据类型的转换。而 set 的查询这么快,其本质是在 Python 内部,set 是使用 hash table 来构建的
  2. 数据是无序的
  3. 数据是不可变变量的
  4. 数据没有重复的
  5. 数据是不可变变量的

 
选择 array 的场景

  1. 需要更节省内存

 

测试结果

结果总结(速度):

  1. 插入大量数据 set > list >> array
  2. 判断存在性 set >>>>>>>>>>>>>> list >> array
  3. 弹出第一个值 array > list
  4. 弹出最后一个值 set > array > list
  5. 在首部插入数据 array >> list
  6. 在尾部插入数据 array ≈ list
  7. 追加数据(append 和 add)list > array > set

 
注意:上述总结中仅涉及对容器自身的操作,若在这些操作之外还有额外操作,主要重点注意 array中的数据转换为 PyObject 的性能开销,除非是数据量特别大,内存需要谨慎分配的场景,其他场景均建议使用 list 而非 array

在这里插入图片描述

 

1、插入 100 万数据的速度比

在这里插入图片描述

 

2、判断存在性,判断的第一个值就存在

在这里插入图片描述

 

3、判断存在性,判断的最后一个值才存在

在这里插入图片描述

 

4、弹出第一个值

在这里插入图片描述

 

5、弹出最后一个值

在这里插入图片描述

 

6、在首部插入数据

在这里插入图片描述

 

7、在尾部插入数据

在这里插入图片描述

 

7、追加数据

在这里插入图片描述

 
 
 
 
 
 
 
 

测试代码


from array import array
from timeit import timeitnumber = 100l = list()
t = timeit("for i in range(100_0000): l.append(i)", number=number, globals=globals())
print(f"[List] List append time: {t:.20f}")a = array("I")
t = timeit("for i in range(100_0000): a.append(i)", number=number, globals=globals())
print(f"[Array] Array append time: {t:.20f}")_s = set()
t = timeit("for i in range(100_0000): _s.add(i)", number=number, globals=globals())
print(f"[Set] Set append time: {t:.20f}")t = timeit("1 in l", number=number, globals=globals())
print(f"[List] First element in list: {t= :.20f}")t = timeit("1 in a", number=number, globals=globals())
print(f"[Array] First element in array: {t= :.20f}")t = timeit("1 in _s", number=number, globals=globals())
print(f"[Set] First element in set: {t= :.20f}")t = timeit("99_9999 in l", number=number, globals=globals())
print(f"[List] Last element in list: {t= :.20f}")t = timeit("99_9999 in a", number=number, globals=globals())
print(f"[Array] Last element in array: {t= :.20f}")t = timeit("99_9999 in _s", number=number, globals=globals())
print(f"[Set] Last element in set: {t= :.20f}")t = timeit("l.pop(0)", number=number, globals=globals())
print(f"[List] List pop 0: {t= :.20f}")t = timeit("a.pop(0)", number=number, globals=globals())
print(f"[Array] Array pop 0: {t= :.20f}")t = timeit("l.pop(-1)", number=number, globals=globals())
print(f"[List] List pop -1: {t= :.20f}")t = timeit("a.pop(-1)", number=number, globals=globals())
print(f"[Array] Array pop -1: {t= :.20f}")t = timeit("_s.pop()", number=number, globals=globals())
print(f"[Set] Set pop random: {t= :.20f}")t = timeit("l.insert(0, 0)", number=number, globals=globals())
print(f"[List] List insert first: {t= :.20f}")t = timeit("a.insert(0, 0)", number=number, globals=globals())
print(f"[Array] Array insert first: {t= :.20f}")t = timeit("l.insert(-1, 0)", number=number, globals=globals())
print(f"[List] List insert last: {t= :.20f}")t = timeit("a.insert(-1, 0)", number=number, globals=globals())
print(f"[Array] Array insert last: {t= :.20f}")t = timeit("l.append(0)", number=number, globals=globals())
print(f"[List] List append: {t= :.20f}")t = timeit("a.append(0)", number=number, globals=globals())
print(f"[Array] Array append: {t= :.20f}")t = timeit("_s.add(0)", number=number, globals=globals())
print(f"[Set] Set append: {t= :.20f}")

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

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

相关文章

【002_音频开发_基础篇_Linux音频架构简介】

002_音频开发_基础篇_Linux音频架构简介 文章目录 002_音频开发_基础篇_Linux音频架构简介创作背景Linux 音频架构ALSA 简介ASoC 驱动硬件架构软件架构MachinePlatformCodec ASoC 驱动 PCMALSA设备文件结构 ALSA 使用常用概念alsa-libALSA Open 流程ALSA Write 流程2种写入方法…

Eclipse+Java+Swing实现学生信息管理系统-TXT存储信息

一、系统介绍 1.开发环境 操作系统:Win10 开发工具 :Eclipse2021 JDK版本:jdk1.8 存储方式:Txt文件存储 2.技术选型 JavaSwingTxt 3.功能模块 4.工程结构 5.系统功能 1.系统登录 管理员可以登录系统。 2.教师-查看学生…

打破国外垄断|暴雨发布纯血国产电脑

要说现在国产手机这边已然进入纯自研模式,但电脑这边却还是仍未打破国外技术垄断。但就在刚刚,暴雨发布自研架构台式机open Station X ,这是纯血鸿蒙系统之后国产又一款纯血产品发布!标志的我们已经彻底打破西方在硬件及软件方面的…

c++ - 空间申请和释放 new/delete

文章目录 一、c/c内存分布二、new/delete 的使用三、malloc/free 和 new/delete 的对比四、new/delete 的实现原理五、匹配问题 一、c/c内存分布 求下面各个变量的位置 // c/c内存分布int globalVar 1; static int staticGlobalVar 1; void Test() {static int staticVar …

PyTorch与深度学习:探索现代神经网络的魅力

在科技飞速发展的今天,深度学习作为人工智能领域的重要分支,已经在图像识别、自然语言处理、语音识别等多个领域取得了突破性的进展。而PyTorch,作为一款开源的深度学习框架,以其简洁易用、动态计算图等特性,赢得了广大…

2024年3月青少年软件编程(Python) 等级考试试卷(一级)

2024.3 青少年软件编程(Python) 等级考试试卷(一级) 一、 单选题(共 25 题, 共 50 分) 1.下列哪个命令, 可以将 2024 转换成 2024 呢? ( ) A.str(2024) B.int(2024) C.fl…

Django中间件的源码解析流程(上)——中间件载入的前置

目录 1. ​前言​ 2. 请求的入口 3. 中间件加载的入口 4. 源码中的闭包实现 5. 最后 1. 前言 哈喽,大家好,我是小K,今天咋们分享的内容是:在学会Django中间件之后, 我们继续深入底层源码。 在执行中间件时请求到来总是从前往后…

ChatGPT研究论文提示词集合3-【数据收集】、【数据分析】和【解释与讨论】

点击下方▼▼▼▼链接直达AIPaperPass ! AIPaperPass - AI论文写作指导平台 目录 1.数据收集 2.数据分析 3.讨论与解释 4.书籍介绍 AIPaperPass智能论文写作平台 近期小编按照学术论文的流程,精心准备一套学术研究各个流程的提示词集合。总共14个步…

【IDEA】用idea导入eclipse的项目后,提示:The file was loaded in a wrong encoding ‘utf-8‘

前言 最近用IDEA导入一个exlipse项目后,窗口出现这个红色提示: 可以项目中的中文,包括注释都是乱码,要解决问题就跟我开始做吧。 一定要看仔细在操作! 一定要看仔细在操作! 一定要看仔细在操作&#xf…

for循环的用法

for循环的用法 for 循环是一种在 Python 中用于迭代序列(如列表、元组或字符串)或其他可迭代对象的循环结构。下面是一些常见的 for 循环用法: 遍历列表:使用 for 循环遍历列表中的元素。 fruits ["apple", "b…

rmallox勒索病毒威胁网络安全:如何避免数据被锁定

尊敬的读者: 随着信息技术的飞速发展,网络空间的安全问题日益凸显。近年来,一种名为.rmallox的勒索病毒频繁出没,给广大计算机用户带来了严重的困扰。本文将对该病毒进行深入剖析,并探讨相应的应对策略。在面对被勒索…

飞书API(5):查看多维表 28 种数据类型的数据结构

一、引入 前面我们用于测试的数据集其实都是比较常用的数据,比如说文本、数字、单选等,但飞书多维表并不仅仅只有这些数据,截止发文,飞书多维表应用上支持28种数据类型,在数据层面飞书官方只提供了23种数据类型&#…

微信小程序vue.js+uniapp服装商城销售管理系统nodejs-java

本技术是java平台的开源应用框架,其目的是简化Sping的初始搭建和开发过程。默认配置了很多框架的使用方式,自动加载Jar包,为了让用户尽可能快的跑起来spring应用程序。 SpinrgBoot的主要优点有: 1、为所有spring开发提供了一个更快…

MySQL数据库——17.正则表达式

MySQL正则表达式是一种强大的模式匹配工具,用于在文本数据中搜索和匹配特定的模式。MySQL使用正则表达式来执行模式匹配的操作,可以在SELECT语句的WHERE子句中使用,也可以在其他SQL语句中使用。 基本语法: 在MySQL中,正则表达式通常与REGEXP关键字一起使用。基本语法如下…

AI 智能工具以及热门AI开源项目整理,包含国内中科院版GPT

AI 智能工具以及热门AI开源项目整理,包含国内中科院版GPT。 不用xx即可访问的镜像网站 https://chat1.yqcloud.top https://chat.bnu120.space https://chat.aidutu.cn https://hzdjs.cn/chatgpt https://chats.fenqubiao.com/zh 需要xx才能访问的网站 https://o…

云原生小疑问 ⁉️ - Kubernetes 下重启容器会丢失数据吗?

文章目录 问题哪些数据需要持久化?解决办法参考 问题 在 docker 环境下,容器重启后还是原来的容器,数据并没有丢失。那是不是 k8s 环境下,重启也不会丢失呢? 在kubernetes/RainBond环境下,最小化的管理单元…

Vue模版语法(初学Vue之v-指令语法)

目录 一、介绍 1.概念 2.常见指令语法及用法 1.v-bind: 2.v-model: 3.v-if / v-else-if / v-else: 4.v-for: 5.v-on: 6.v-show: 7.v-pre: 8.v-cloak: 二、使用 1.Mustache插值语法 2.v-once指令使用 3.v-text指令使用 4.v-html指令使用 5.v-pre指令使用 6.v-…

「 网络安全常用术语解读 」什么是0day、1day、nday漏洞

1. 引言 漏洞攻击的时间窗口被称为漏洞窗口(window of vulnerability)。一般来说,漏洞窗口持续的时间越长,攻击者可以利用漏洞进行攻击的可能性就越大。 2. 0day 漏洞 0day 漏洞,又被称为"零日漏洞"&…

Ocelot扩展应用

Ocelot 是一个灵活且可扩展的 API 网关框架,它可以在各种应用场景中扩展和定制。通过扩展 Ocelot,你可以在网关中添加各种自定义功能、集成第三方服务以及优化性能。以下是一些 Ocelot 扩展应用的示例: 1. 自定义中间件: Ocelot…

react之组件与JSX

第一章 - 描述用户界面 概述:React是一个用于构建用户界面(UI)的JavaScript库,用户界面由按钮,文本和图像等小单元内容构建而成。React帮助你把它们组合成可重用,可嵌套的组件。从web端网站到移动端应用&a…