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


读有趣的书 “从Python到Numpy” 我遇到了一个 ,其描述如下:

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

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

变种在三台不同的计算机上定时:我的(Win10Win7的)和作者(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         |

正如您在此表中所看到的那样 视窗 结果不依赖于查看的类型,而是依赖于 OS X. 这个黑客高度影响了性能。 您能否提供有关这种情况的见解?

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

第一台电脑的规格: 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

第三台电脑的规格: 我没有这个信息:)

链接到该问题

编辑2:添加结果 第一台电脑 上 Ubuntu 17.10


11350
2018-03-28 18:04


起源

除非您使用相同的硬件测试相同的代码执行,否则如果没有差异,我会感到非常惊讶。 - user1767754
@ user1767754公平点但不相关听到。它似乎是依赖于os的行为,因为两台完全不同的计算机之间的结果在一个操作系统上是一致的,而在另一个操作系统上则不一致。 - godaygo
但是硬件 不 物。这一切都归结为最终的硬件。 - Simon
这听起来像是可用的指令或编译器选择的指令的区别,而不是操作系统的东西。 - user2357112
将数组归零所达到的速度在很大程度上取决于编译器在每种情况下为内循环选择的少数指令。不同的编译器会给出截然不同的结果,这一点都不奇怪。另一个重要变量是如何分配大型数组。在某些库/ OS组合中,在写入内存之前不会映射物理页面。如果在这种情况下发生这种情况,页面映射的成本将作为归零的一部分来支付。通过在测量之前将其编写一次来“预热”阵列会更加真实(如果作者没有这样做)。 - Gene


答案:


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

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

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

然而,你只需要这样做 arr = [1, 2, 3],而不是担心它。

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

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

例如,有一个 老答案 np.dot Linux和Windows之间的功能性能不同。作者在这个主题上有比我更多的知识,并指出该特定函数是CBLAS例程的包装器,它将使用给定平台上可用的最快例程。

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


10
2018-04-18 12:42