【问题标题】:Very basic CS question - does number sorting speed depend on integer size?非常基本的 CS 问题 - 数字排序速度是否取决于整数大小?
【发布时间】:2021-02-02 22:52:02
【问题描述】:

我没有 CS 背景,所以对于我认为是基本问题的问题,我深表歉意。但出于好奇,如果我要对 [3,2,1] 与 [3e100, 2e100, 1e100] 进行排序,是否存在速度差异(即使是分钟)?

【问题讨论】:

  • 如果所有数字都适合内存的同一部分,并且被硬件的所有相关部分处理相同,那么速度是相同的。
  • 为什么不进行基准测试并找出真正的答案;)
  • 这在很大程度上取决于数字 3e1002e100 等在内部如何表示(浮点数、任意精度整数,还是其他?)以及机器能够比较的效率如何任意两个。

标签: algorithm computer-science


【解决方案1】:

可能有也可能没有。与数学理论和原理有关的“计算机科学”与与制作实际软件有关的“软件工程”或“编程”是有区别的。


在计算机科学中,这样的细节在一般情况下并不重要。如果您在黑板上定义一个给定的场景以具有这样的速度差异,它确实如此。您可以轻松地将黑板场景定义为有这样的速度差异。这取决于您和您正在处理的任何问题空间,但无论哪种方式,这主要是一个黑板数学问题,而不是真正的、字面上的计算机。


在软件工程/编程/开发/无论您怎么称呼它,这都取决于具体情况。作为一般经验法则,对[2, 1, 3][200, 1, 30000] 进行排序可能会平均花费相似的时间(如果不相等的话)。但是,排序 [2, 1, 3] 和排序 [2000000000, 1, 300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000] 可能会在速度上看到有意义的差异。

原因在于它在很大程度上与用于存储数字的位数有关。它也可能与不同的字节和内容在内存中的存储位置以及诸如此类的事情有关,但仅位大小的差异就足以证明一个体面的例子。

以 32 位整数为例。 非常通常使用 32 位(或者在某些情况下,64,但更常见的是 32)来存储数字。例如,如果我们有任何 非负 整数的 32 位,我们现在将有一个介于 0 和 4,294,967,295 之间的数字。这就是该范围内的一些数字在计算机中的存储方式:

            0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
            1: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
            2: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 10
            3: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 11
            4: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00
            5: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01
            6: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 10
            7: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 11
            8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 10 00
                                     ...
           15: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 11 11
           16: 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00
                                     ...
4,294,967,295: 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11

如您所见,0、1、15 和 4,294,967,295 分别占用相同数量的空间。基本上来说,计算机对这些数字中的任何一个进行算术运算与对其余任何一个数字进行算术运算的麻烦程度相同。它们在概念上可能更大或更小,但在计算机中,它们都需要相同数量的信息来存储。

(由于通常与硬件本身非常接近的原因,可能会有一些差异;但是我个人不确定这会产生多大的差异,这超出了这个问题的范围. 软件和硬件是两个不同的领域。)

现在...现在,假设我们要存储上面提到的巨大的数字:即 3000000000000000000000000000000000000000000000000000000000000000000000000000000。

那么,赫克,300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000比4294967295更大一大堆,和4294967295已经比可以用32位被存储的最大数。 P>

那么,我们的 64 位选项呢?可以容纳的最大整数是 18,446,744,073,709,551,616,它仍然比上面列出的大而大的数字小 很多。如此完全直接,运行 64 位存储也是不可能的。

因此,在用完典型大小的内存后,您就开始将大量内存分成更小的块。您不会将其全部存储在一个 32 位或 64 位位置。而是将其存储在多个中。

这就是您看到速度差异的地方。对于每个都可以放入 32 位或 64 位(甚至 8 或 16 位)的较小数字,计算机只需为每个数字查找一个小点。对于庞大的数字,它必须查看潜在的几个。而当它必须查看多个点时,将需要额外的时间 - 是的,绝对如此。


现在,说了这么多,如果你真的想的话,你仍然可以将这个巨大的数字(30000000...)存储在 32 位或 64 位中。但是,您不能仅以基本方式存储它。您必须使用特殊格式,对所有1s 和0s 具有特殊含义。您可以根据3 x 10^(89) 而不是30000000000... 来安排它们。例如,您可以执行以下操作:

         89|                                  3
-----------|-----------------------------------
01 01 10 01|00 00 00 00 00 00 00 00 00 00 00 11

这将是 32 位,但它只使用前 8 位来存储 10^(89) 部分,然后使用剩余的 24 位来存储 3 部分。

这带来的问题是复杂性。它使程序员、QA 人员和可能涉及的其他人员的工作复杂化。

但是,它也使计算机处理数字的方式变得复杂。 计算机本身将无法理解上述格式。您的代码 - 或者您的代码构建于其之上的某些工具,可能是实际的编程语言本身 - 将必须 翻译 来回转换成计算机可以理解的格式或其他格式。即便如此,它仍然会变得如此之大,以至于计算机一次只能处理一个。


总结一下,这里有几件事:

  1. 计算机科学和软件工程是两个不同的东西。
  2. 软件工程和硬件工程是两个不同的东西。
  3. 在黑板上,数字大小不会影响速度,基本上除非你想要它们。
  4. 对于大多数日常高级编程(像 JavaScript 之类的东西,而不是像 Assembly 之类的东西),程序员始终需要关心并没有区别。大多数时候,我们至少假装根本不存在差异。至少有时,它可能真的不存在。
  5. 但是,可能在硬件级别上有所不同。但是当我们处理像 JavaScript 这样的高级语言,而不是像 Assembly 和 C++ 这样的中低级语言时,我们通常不必担心什么。实际上,即使是 C++ 程序员也可能不必担心很多次。
  6. 但是,如果我们处理的是超大数字,可能会出现在科学软件或其他类似软件中,那么绝对 100% 存在 #4 的例外情况。

【讨论】:

    【解决方案2】:

    如果您正在处理numbers of arbitrary size,那么显然需要更多时间来处理涉及用更多字节表示的大量数字。

    如果您正在处理具有固定宽度表示的传统数字(例如 32 位整数、IEEE-754 双精度浮点数):也许

    例如,对字节数组中的单个字节进行排序可能比对 32 位整数进行排序要慢,因为大多数硬件必须生成额外的屏蔽和移位指令来读取和写入单个字节。 (另一方面,SIMD instructions 可以同时对较小的数据进行多次比较。)

    再举一个例子,如果您进行基于比较的排序,比较 1 和 232 - 1(从最高有效位可以明显看出差异)可能比比较快一些2 和 3(在最低有效位之前没有区别)在硬件上按顺序和串行比较位。在实践中,尤其是在现代硬件上,不太可能有任何明显的差异。

    从计算机科学的角度来看,这些都不是很有趣。它取决于硬件,任何差异都只是运行时复杂性的一个恒定因素。人们关心的是运行时复杂性如何相对于输入的大小增长。对于具有固定大小表示的数字,输入大小的这一方面是恒定的,因此输入大小意味着要排序的项目数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-17
      • 1970-01-01
      • 1970-01-01
      • 2011-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多