微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

非常基本的 CS 问题 - 数字排序速度是否取决于整数大小?

如何解决非常基本的 CS 问题 - 数字排序速度是否取决于整数大小?

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

解决方法

可能有也可能没有。与数学理论和原理有关的“计算机科学”与与制作实际软件有关的“软件工程”或“编程”之间存在差异。


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


在软件工程/编程/开发/不管你想怎么称呼它,这取决于具体情况。作为一般经验法则,排序 [2,1,3] 和排序 [200,30000] 的平均时间可能相似(如果不相等)。然而,排序 [2,3] 和排序 [2000000000,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,295: 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11

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

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

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

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

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

因此,在用完典型大小的内存后,您就开始将庞大的数字分解成更小的块。您不会将其全部存储在一个 32 位或 64 位位置;相反,您将其存储在多个。

这就是您看到速度差异的地方。对于每个都可以容纳 32 位或 64 位(甚至 8 位或 16 位)的较小数字,计算机只需查看每个数字的一​​个小点。对于庞大的数字,它必须考虑可能的几个。当它必须查看多个点时,需要额外的时间 - 是的,绝对。


现在,综上所述,如果您真的愿意,您仍然可以以 32 位或 64 位的形式存储巨大的数字(30000000...)。但是,您不能仅以基本方式存储它。您必须使用特殊格式,对所有这些 10 具有特殊含义。您可以根据 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 之类的东西,而不是汇编之类的东西),程序员经常需要关心的内容并没有什么不同。大多数时候,我们至少假装根本不存在差异。至少有时,它可能真的不存在。
  5. 但是,可能在硬件级别上有所不同。但是当我们处理像 JavaScript 这样的高级语言,而不是像 Assembly 和 C++ 这样的中低级语言时,通常我们不必担心什么。事实上,即使是 C++ 程序员也可能不必担心很多次。
  6. 但如果我们正在处理超大数字,这可能会出现在科学软件或其他类似的东西中,那么 #4 的例外绝对存在,100% 存在。
,

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

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

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

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

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。