numpy的性能是否因操作系统而异?

时间:2018-03-28 18:04:04

标签: python performance numpy memory

阅读有趣的书"From Python to Numpy"我遇到了example,其描述如下:

  

让我们考虑一个我们想要清除所有值的简单示例   来自具有dtype np.float32的数组。如何写它   最大化速度?

提供的结果让我感到惊讶,当我重新检查它们时,我得到了完全不同的行为。所以,我要求作者仔细检查,但他在下表中收到了与之前相同的结果( OS X 10 ):

这些变体在三台不同的计算机上计时:我的( Win10 Win7 )和作者( OSX 10.13.3 )。使用 Python 3.6.4 numpy 1.14.2 ,其中每个变体都是针对固定的 100循环计时,最好是3

编辑:这个问题不是关于这样一个事实:在不同的计算机上,具有不同的特征,我得到不同的时间 - 这是显而易见的:) 问题是两个操作的行为是非常不同的系统 - 哪个不那么明显?(如果当然如此,如果有人可以仔细检查,我会很高兴。)

设置为:Z = np.ones(4*1000000, np.float32)

| Variant                     | Windows 10 | Ubuntu 17.10 | Windows 7 | OSX 10.13.3 |
|                             |       computer 1          |   comp 2  |    comp 3   |
| --------------------------- | ------------------------- | --------- | ----------- |
| Z.view(np.float64)[...] = 0 | 758 usec   | 1.03 msec    | 2.72 msec | 1.01 msec   |
| Z.view(np.float32)[...] = 0 | 757 usec   | 1.01 msec    | 2.61 msec | 1.58 msec   |
| Z.view(np.float16)[...] = 0 | 760 usec   | 1.01 msec    | 2.62 msec | 2.85 msec   |
| Z.view(np.complex)[...] = 0 | 1.06 msec  | 1.02 msec    | 3.26 msec | 918 usec    |
| Z.view(np.int64)[...] = 0   | 758 usec   | 1.03 msec    | 2.69 msec | 1 msec      |
| Z.view(np.int32)[...] = 0   | 757 usec   | 1.01 msec    | 2.62 msec | 1.46 msec   |
| Z.view(np.int16)[...] = 0   | 760 usec   | 1.01 msec    | 2.63 msec | 2.87 msec   |
| Z.view(np.int8)[...] = 0    | 758 usec   | 773 usec     | 2.68 msec | 614 usec    |
| Z.fill(0)                   | 747 usec   | 998 usec     | 2.55 msec | N/A         |
| Z[...] = 0                  | 750 usec   | 1 msec       | 2.59 msec | N/A         |

从此表中可以看出,在 Windows 上,结果不依赖于查看的类型,但在 OS X 上,此hack会严重影响性能。 您能否提供有关这种情况的见解?

编辑 :正如我上面写的那样,三台电脑不同。

第一台计算机的规格 : Windows 10和Ubuntu 17.10
CPU:Intel Xenon E5-1650v4 3.60GHz
内存:128GB DDR4-2400

第二台计算机的规格 : Windows 7
CPU:Intel Pentium P6100 2.00GHz
内存:4GB DDR3-1333

第三台计算机的规格 : 我没有这个信息:)

Link to the issue

编辑2 :在 Ubuntu 17.10 上添加第一台计算机的结果。

1 个答案:

答案 0 :(得分:10)

请记住,Python是一种非常高级的编程语言,Pandas也是一个高级框架。

您实际使用的是用于许多操作的高级API,您可以使用该语言执行该操作,而无需担心底层实现。

如果您使用的是较低级别的API,要将数组分配给变量,您必须分配一些内存,创建一个结构来保存数据,将它们链接在一起(可能使用指向内存地址的指针) 。而你甚至没有触及实际芯片,你的API和保存到芯片的实际数据之间仍然存在虚拟内存映射。而且这种复杂性基本上适用于您使用Python&大熊猫。

然而,你只需做arr = [1, 2, 3],而不用担心。

现在,Python应该在您运行它的每个平台上运行相同 - 至少在大多数情况下。

现在,在枯燥乏味的介绍落后于我们之后 - “暴露统一API,不担心实现”的整个想法在计算机编程中得到广泛传播。有一些微妙的实现细节使一个操作系统与另一个操作系统不同,这可能会也可能不会影响软件的性能。我不认为这很重要,但它仍然存在,值得一提。

例如,有一个old answer about np.dot function performance differing between Linux and Windows。作者在这个主题上有比我更多的知识,并指出该特定函数是CBLAS例程的包装器,它将使用给定平台上可用的最快例程。

话虽这么说 - 熊猫是一个非常复杂的库,旨在通过向程序员公开简单易用的API,使数据分析尽可能简单。我希望Pandas可以使用您平台上可用的最佳机制尽可能快地完成任务。