写python代码这么多年,从来也没有想过不同方式的读取python数组会有什么太大的性能差距,不过这段时间写代码突然发现这个差别还挺大,于是就多研究了一下。

本文研究的是使用不同方式来对python数组进行按索引读取的性能差别。下面分别使用4种按索引读取数组的方法(不同方法中的数组都是相同形态的):

第一种,按索引读取一维的numpy数组;

第二种,按索引读取多维的numpy数组;

第三种,按索引读取一维的python列表;

第四种,按索引读取多维的python列表。

 
 
 

具体代码:

import numpy as np
import time total = 16**6
data_0 = np.arange(0,16**6)
data_1 = data_0.reshape(16, 16, 16, 16, 16, 16)
data_2 = data_0.tolist()
data_3 = data_1.tolist() num = 3*(10**6)
indexes_list_0 = np.random.randint(total, size=(num,)).tolist()
indexes_list_1 = []
for _ in range(num):
indexes_list_1.append(np.random.randint(16, size=(6,)).tolist())
indexes_list_2 = indexes_list_0
indexes_list_3 = indexes_list_1 a_time = time.time()
for index in indexes_list_0:
ans = data_0[index]
b_time = time.time()
print(b_time-a_time) a_time = time.time()
for a,b,c,d,e,f in indexes_list_1:
ans = data_1[a,b,c,d,e,f]
b_time = time.time()
print(b_time-a_time) a_time = time.time()
for index in indexes_list_2:
ans = data_2[index]
b_time = time.time()
print(b_time-a_time) a_time = time.time()
for a,b,c,d,e,f in indexes_list_3:
ans = data_3[a][b][c][d][e][f]
b_time = time.time()
print(b_time-a_time)

 运行性能: 

分析:

从上面可以看到:

1. 不论是对numpy数组还是list列表,使用一维索引的性能往往要高于多维索引的2倍以上性能;

2. 相同形式下使用索引方式读取数组,numpy数组的读取性能要由于list列表性能;

3. 性能排序,一维索引读取numpy数组性能 > 一维索引读取list性能 > 多维索引读取numpy数组性能 > 多维索引读取list性能。

=======================================

在上面的例子中,我们对一维数据的读取都是直接有索引号的,但是如果我们对一维数据索引时索引号和对多维数据读取时一样都是多维索引号,那么性能又该如何呢?

在对一维数组读取时使用多维索引号,将多维索引号转为一维索引后再对一维数组读取。

代码:

import numpy as np
import time total = 16**6
data_0 = np.arange(0,16**6)
data_1 = data_0.reshape(16, 16, 16, 16, 16, 16)
data_2 = data_0.tolist()
data_3 = data_1.tolist() num = 3*(10**6)
indexes_list_0 = np.random.randint(total, size=(num,)).tolist()
indexes_list_1 = []
for _ in range(num):
indexes_list_1.append(np.random.randint(16, size=(6,)).tolist())
indexes_list_2 = indexes_list_0
indexes_list_3 = indexes_list_1 a_time = time.time()
for a,b,c,d,e,f in indexes_list_1:
index = (16**5)*a+(16**4)*b+(16**3)*c+(16**2)*d+16*e+f
ans = data_0[index]
b_time = time.time()
print(b_time-a_time) a_time = time.time()
for a,b,c,d,e,f in indexes_list_1:
ans = data_1[a,b,c,d,e,f]
b_time = time.time()
print(b_time-a_time) a_time = time.time() for a,b,c,d,e,f in indexes_list_1:
index = (16**5)*a+(16**4)*b+(16**3)*c+(16**2)*d+16*e+f
ans = data_2[index]
b_time = time.time()
print(b_time-a_time) a_time = time.time()
for a,b,c,d,e,f in indexes_list_3:
ans = data_3[a][b][c][d][e][f]
b_time = time.time()
print(b_time-a_time)

运行性能:

分析:

发现当对一维数组读取时,加入了将多维索引号转为一维索引号的操作后,运行性能急剧的下降。最后,我们可以发现,当加入索引号转换操作后,性能最高的读取方式为numpy的多维数组索引读取。

在很多运行情况中,我们往往都是直接获得多维索引号,而这个时候使用numpy的多维索引是性能最好的。

====================================================

python中不同方法的按索引读取数组的性能比较——哪种按索引读取数组的性能更好的更多相关文章

  1. C# 字符串拼接性能探索 c#中+、string.Concat、string.Format、StringBuilder.Append四种方式进行字符串拼接时的性能

    本文通过ANTS Memory Profiler工具探索c#中+.string.Concat.string.Format.StringBuilder.Append四种方式进行字符串拼接时的性能. 本文 ...

  2. python中快速获取本地时区当天0点时间戳的一种方法

    如下所示,看了网上的几种方法,这种方法算是代码量比较小的,同时可以保证求的是本地时区的0点时间戳,返回的是浮点数,需要的话自己转一下int In [1]: import time In [2]: fr ...

  3. Python学习笔记整理(四)Python中的字符串..

    字符串是一个有序的字符集合,用于存储和表现基于文本的信息. 常见的字符串常量和表达式 T1=‘’ 空字符串 T2="diege's" 双引号 T3=""&quo ...

  4. 《python解释器源码剖析》第4章--python中的list对象

    4.0 序 python中的list对象,底层对应的则是PyListObject.如果你熟悉C++,那么会很容易和C++中的list联系起来.但实际上,这个C++中的list大相径庭,反而和STL中的 ...

  5. python中的常用数据类型

    python中的常用数据类型 以下是个人总结的python中常见的数据类型,话不多说,我们直接步入正题: 数字类型 整型类:int类可以表示任意大小的整数值,在python中没有像JAVA或者C那样的 ...

  6. python中的文件的读写

    python中的 w+ 的使用方法:不能直接 write() 后,在进行读取,这样试读不到数据的,因为数据对象到达的地方为文件最后,读取是向后读的,因此,会读到空白,应该先把文件对象移到文件首位. f ...

  7. Python中通过open()操作文件时的文件中文名乱码问题

    最近在用Python进行文件操作的时候,遇到创建中文文件名的乱码问题. Python默认是不支持中文的,一般我们在程序的开头加上#-*-coding:utf-8-*-来解决这个问题,但是在我用open ...

  8. python中栈的实现

    栈是一种线性数据结构,用先进后出或者是后进先出的方式存储数据,栈中数据的插入删除操作都是在栈顶端进行,常见栈的函数操作包括 empty() – 返回栈是否为空 – Time Complexity : ...

  9. Python 中的枚举类型~转

    Python 中的枚举类型 摘要: 枚举类型可以看作是一种标签或是一系列常量的集合,通常用于表示某些特定的有限集合,例如星期.月份.状态等. 枚举类型可以看作是一种标签或是一系列常量的集合,通常用于表 ...

  10. 【转】Python中的赋值、浅拷贝、深拷贝介绍

    这篇文章主要介绍了Python中的赋值.浅拷贝.深拷贝介绍,Python中也分为简单赋值.浅拷贝.深拷贝这几种"拷贝"方式,需要的朋友可以参考下   和很多语言一样,Python中 ...

随机推荐

  1. Css var 的基础使用

    Css var 语法 var(custom-property-name, value) - custom-property-name 必须 变量必须以 --开头 后面可以是英文.数字连接符,区分大小写 ...

  2. gradle打包命令含离线模式

    gradle打包命令gradlew clean 清理gradlew clean build -x test --refresh-dependencies 离线方式: gradlew --offline ...

  3. Thread的join方法demo

    Thread的join方法demo /** * 关于join官方的解释是 Waits for this thread to die. 也就是等待一个线程结束. */ public class Thre ...

  4. Navicat Premium v16.0.6 绿色破解版

    这里版本:Navicat Premium v16.0.6.0 ,这个是绿色版,不需要安装,启动Navicat.exe即可用 破解工具:NavicatKeygenPatch(其它版本也能破解) 1.下载 ...

  5. iterrows()

    iterrows() 是 Pandas 库中 DataFrame 对象的一个方法,它允许你迭代 DataFrame 的行.当你有一个 DataFrame 并且想要逐行访问数据(或者基于每一行的数据做一 ...

  6. Nuxt 3组件开发与管理

    title: Nuxt 3组件开发与管理 date: 2024/6/20 updated: 2024/6/20 author: cmdragon excerpt: 摘要:本文深入探讨了Nuxt 3的组 ...

  7. 《Vue3.x +TpyeScript实践指南》勘误

    图书出版已有一段时间,书中已发现错误如下: 书的第14页,倒数第3行,npm init -y命令中,init和-y之间应该有个空格: 书的第32页,代码的第1行,应该为模板字符串符号 `,我看印刷的是 ...

  8. hive第二课:Hive3.1.2概述与基本操作(修改版)

    Hive3.1.2概述与基本操作 1.Hive基本概念 1.1 Hive简介 Hive本质是将SQL转换为MapReduce的任务进行运算,底层由HDFS来提供数据存储,说白了hive可以理解为一个将 ...

  9. 瑞芯微RK3568J如何“调节主频”,实现功耗降低?一文教会您!

    RK3568J主频模式说明 为降低RK3568J功耗,提高运行系统健壮性,在产品现场对RK3568J实现主频调节则显得尤为重要. 图 1 RK3568J官方数据手册主频模式描述 normal模式 根据 ...

  10. gdb 根据c语言二进制文件进程号查看内部多线程任务

    C语言二进制文件 a 编译时添加了 -g (gdb 调试), 但是 gdb a 这种方式有时不容易复现一些场景.这时可以先正常启动 a, 然后根据 a 的进程号启动gdb调试. # 1. 找到程序进程 ...