当前位置: 首页 > 面试题库 >

Python Numpy数据类型性能

荣波
2023-03-14
问题内容

所以我做了一些测试,结果很奇怪。

码:

import numpy as np
import timeit


setup = """
import numpy as np
A = np.ones((1000,1000,3), dtype=datatype)
"""

datatypes = "np.uint8", "np.uint16", "np.uint32", "np.uint64",  "np.float16", "np.float32", "np.float64"

stmt1 = """
A = A * 255
A = A / 255
A = A - 1
A = A + 1
"""
#~ np.uint8 : 1.04969205993
#~ np.uint16 : 1.19391073202
#~ np.uint32 : 1.37279821351
#~ np.uint64 : 2.99286961148
#~ np.float16 : 9.62375889588
#~ np.float32 : 0.884994368045
#~ np.float64 : 0.920502625252

stmt2 = """
A *= 255
A /= 255
A -= 1
A += 1
"""
#~ np.uint8 : 0.959514497259
#~ np.uint16 : 0.988570167659
#~ np.uint32 : 0.963571471946
#~ np.uint64 : 2.07768933333
#~ np.float16 : 9.40085450056
#~ np.float32 : 0.882363984225
#~ np.float64 : 0.910147440048

stmt3 = """
A = A * 255 / 255 - 1 + 1
"""
#~ np.uint8 : 1.05919667881
#~ np.uint16 : 1.20249978404
#~ np.uint32 : 1.58037744789
#~ np.uint64 : 3.47520357571
#~ np.float16 : 10.4792515701
#~ np.float32 : 1.29654744484
#~ np.float64 : 1.80735079168

stmt4 = """
A[:,:,:2] *= A[:,:,:2]
"""
#~ np.uint8 : 1.23270964172
#~ np.uint16 : 1.3260807837
#~ np.uint32 : 1.32571002402
#~ np.uint64 : 1.76836543305
#~ np.float16 : 2.83364821535
#~ np.float32 : 1.31282323872
#~ np.float64 : 1.44151875479

stmt5 = """
A[:,:,:2] = A[:,:,:2] * A[:,:,:2]
"""
#~ np.uint8 : 1.38166223494
#~ np.uint16 : 1.49569114821
#~ np.uint32 : 1.53105315419
#~ np.uint64 : 2.03457943366
#~ np.float16 : 3.01117795524
#~ np.float32 : 1.51807271679
#~ np.float64 : 1.7164808877

stmt6 = """
A *= 4
A /= 4
"""
#~ np.uint8 : 0.698176392658
#~ np.uint16 : 0.709560468038
#~ np.uint32 : 0.701653066443
#~ np.uint64 : 1.64199069295
#~ np.float16 : 4.86752675499
#~ np.float32 : 0.421001675475
#~ np.float64 : 0.433056710408

stmt7 = """
np.left_shift(A, 2, A)
np.right_shift(A, 2, A)
"""
#~ np.uint8 : 0.381521115341
#~ np.uint16 : 0.383545967785
#~ np.uint32 : 0.386147272415
#~ np.uint64 : 0.665969478824


for stmt in [stmt1, stmt2, stmt3, stmt4, stmt5, stmt6, stmt7]:
    print stmt
    for d in datatypes:
        s = setup.replace("datatype", d)
        T = timeit.Timer(stmt=stmt, setup=s)
        print d,":", min(T.repeat(number=30))
    print
print

为什么float16这么慢?为什么float32这么快?它通常比整数运算要快。

如果您有任何相关的性能提示,我将很高兴听到它们。

这是Windows 8 64bit上的python 2.6.6 32bit。Numpy 1.6的数字与Numpy
1.7相似。现在将测试MKL优化版本:http :
//www.lfd.uci.edu/~gohlke/pythonlibs/#numpy

编辑:事实证明,在某些浮点情况下,MKL版本稍快一些,但对于整数运算,有时会慢很多:

stmt2 = """
A *= 255
A /= 255
A -= 1
A += 1
"""
#np1.6
#~ np.uint8 : 0.959514497259
#~ np.uint16 : 0.988570167659
#~ np.uint32 : 0.963571471946
#~ np.uint64 : 2.07768933333
#~ np.float16 : 9.40085450056
#~ np.float32 : 0.882363984225
#~ np.float64 : 0.910147440048

# np1.7
#~ np.uint8 : 0.979
#~ np.uint16 : 1.010
#~ np.uint32 : 0.972
#~ np.uint64 : 2.081
#~ np.float16 : 9.362
#~ np.float32 : 0.882
#~ np.float64 : 0.918

# np1.7 mkl
#~ np.uint8 : 1.782
#~ np.uint16 : 1.145
#~ np.uint32 : 1.265
#~ np.uint64 : 2.088
#~ np.float16 : 9.029
#~ np.float32 : 0.800
#~ np.float64 : 0.866

问题答案:

我猜半精度算术(float16)必须由numpy“模仿”,因为在底层C语言(以及适当的处理器指令)中没有相应的类型。另一方面,使用本机数据类型可以非常有效地完成单精度(float32)和双精度(float64)操作。

从单精度运算的良好性能开始:现代处理器具有用于矢量化浮点算术(例如AVX)的有效单元,因为它还需要良好的多媒体性能。



 类似资料:
  • 我有几个表存储了相当大的数字,因此我选择作为所有列的数据类型。 架构示例: Table1(value1,value2,value3,value4,value5) Table2(value1,value2,value3,value4,value5)

  •   MLlib既支持保存在单台机器上的本地向量和矩阵,也支持备份在一个或多个RDD中的分布式矩阵。本地向量和本地矩阵是简单的数据模型,作为公共接口提供。底层的线性代数操作通过Breeze和jblas提供。 在MLlib中,用于有监督学习的训练样本称为标注点(labeled point)。 1 本地向量(Local vector)   一个本地向量拥有从0开始的integer类型的索引以及doubl

  • NumPy 数字类型是dtype(数据类型)对象的实例,每个对象具有唯一的特征。 这些类型可以是,np.float32等。 数据类型对象描述了对应于数组的固定内存块的解释,取决于以下方面: 数据类型(整数、浮点或者 Python 对象) 数据大小 字节序(小端或大端) 在结构化类型的情况下,字段的名称,每个字段的数据类型,和每个字段占用的内存块部分。 如果数据类型是子序列,它的形状和数据类型。 字

  • 数据类型 可以通过 (type x) 来获取 x 的类型. 来自 JavaScript 的数据类型 nil, 对应 null Number Boolean String RegExp cljs 当中正则的语法是 #"\\d" 对应 js 里 /\d/. \d 本来是字符类型, 在 js 环境中成了 String. ClojureScript 其他常用的类型 Keyword, :demo, 或者从

  • 一、存储种类和数据类型: SQLite将数据值的存储划分为以下几种存储类型: NULL: 表示该值为NULL值。 INTEGER: 无符号整型值。 REAL: 浮点值。 TEXT: 文本字符串,存储使用的编码方式为UTF-8、UTF-16BE、UTF-16LE。 BLOB: 存储Blob数据,该类型数据和输入数据完全相同。 由于SQLite采用的是动态数据类型,而其他传统的关系型数据库使用的是静态

  • Perl是一种松散类型的语言,在程序中使用时无需为数据指定类型。 Perl解释器将根据数据本身的上下文选择类型。 Perl有三种基本数据类型:标量,标量数组和标量散列,也称为关联数组。 以下是有关这些数据类型的一些细节。 Sr.No. 类型和描述 1 Scalar 标量是简单的变量。 它们前面有一个美元符号($)。 标量可以是数字,字符串或引用。 引用实际上是变量的地址,我们将在后面的章节中看到。