Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
ruby数组中shift/unshift的运行时间是多少_Ruby_Big O - Fatal编程技术网

ruby数组中shift/unshift的运行时间是多少

ruby数组中shift/unshift的运行时间是多少,ruby,big-o,Ruby,Big O,有人知道在ruby数组中移位和取消移位的效率吗 从数组的开头删除并移动内存中的每个元素可能会变得非常低效。我想ruby是用另一种方式做的 有关以下内容的任何信息都会有所帮助: -算法运行时 -实施 -一般效率 -对于队列(例如C++中的这一点),将使用移位/ unSHIFT() 谢谢大家! 您可以查看unshift方法的C源代码(只需单击描述块)。很明显:如果内存不足,增加内存容量,向前移动数组的当前内容,将传递的参数复制到内存块开头的可用空间。所以它是O(n)对于unshift根据,它似乎根本

有人知道在ruby数组中移位和取消移位的效率吗

从数组的开头删除并移动内存中的每个元素可能会变得非常低效。我想ruby是用另一种方式做的

有关以下内容的任何信息都会有所帮助:
-算法运行时
-实施
-一般效率
-对于队列(例如C++中的这一点),将使用移位/ unSHIFT(


谢谢大家!

您可以查看
unshift
方法的C源代码(只需单击描述块)。很明显:如果内存不足,增加内存容量,向前移动数组的当前内容,将传递的参数复制到内存块开头的可用空间。所以它是O(n)对于
unshift

根据,它似乎根本没有移动,只是增加一个指针并返回它。所以就效率而言,它的效率是荒谬的(O(1))。然而,本文提到了一个潜在的内存泄漏,在最近的版本中可能存在,也可能不存在。

我发现,解决这个问题最简单、最明确的方法就是对其进行基准测试

require 'benchmark'

Benchmark.bm do |x|
    iterations = 10000000
    x.report("push") {
        a = []
        iterations.times do a.push(10) end
    }
    x.report("unshift") {
        a = []
        iterations.times do a.unshift(10) end
    }
    a = []
    iterations.times do a.push(10) end
    x.report("shift") {
        iterations.times do a.shift() end
    }
    a = []
    iterations.times do a.push(10) end
    x.report("pop") {
        iterations.times do a.pop() end
    }
end
在我运行ruby版本
2.0.0
的系统上,这将返回结果:

             user     system      total        real
push     0.880000   0.030000   0.910000 (  0.917213)
unshift  0.920000   0.090000   1.010000 (  1.026208)
shift    0.780000   0.030000   0.810000 (  0.810293)
pop      0.710000   0.000000   0.710000 (  0.724865)
似乎
push
pop
shift
unshift
所用的时间大致相同

再次使用不同的
迭代次数值运行此代码
会得到与我更改的
迭代次数
成比例的结果。这意味着,无论迭代次数的值是多少,每个操作的平均时间总是相同的,这意味着每个操作的运行时间与数组的长度无关,因此运行时间为
O(1)

我认为这可以作为队列使用。

在Ruby的较旧版本(2012年之前)中,
unshift
是一个O(n)操作。但是,增加了一个优化,使得
取消移位
摊销为O(1),这意味着平均保证为O(1),但单个操作可能为O(n)。这与
shift
的运行时间相同


它很好地解释了这是如何工作的,以及如何得到一个O(1)摊销的运行时间(关于C++的
vector::push_back
,但它的工作方式是相同的)。

在1.9.3中,方法的实现变得有点复杂,在某些情况下确实移动了内存。它与使用中的指针类型有关,但我不太确定这个
ARY\u SHARED\u P(ARY)
什么时候是真的,什么时候不是。对不起,“线性缩放”表示O(n)。O(1)表示所需时间与项目数量无关。对于一组运行的计时信息,您无法说明算法的伸缩性。按照测试设置的方式,在每个迭代中使用不同数量的项在阵列上测试操作。这也妨碍了测量它的伸缩性。相反,测试数组中少量项(比如10项)的操作需要多长时间,以及数组中大量项(比如1000项)的操作需要多长时间。重复测试并对结果取平均值。重新阅读答案后,我的评论有点不准确。现在编辑已经太晚了,请参见下面的更新评论。抱歉,“线性缩放”表示O(n)。O(1)表示与项目数量无关的恒定时间。您提供了一组运行的计时信息,因此我们无法看到算法的伸缩性。测量数组中少量项目(比如10个)的操作需要多长时间,以及数组中大量项目(比如1000个)的操作需要多长时间,这会更清楚。重复测试并平均结果。如果操作在小型阵列和大型阵列上花费的时间大致相同,则为O(1)。如果大数组需要大约100倍的时间(线性),那么它就是O(n)。@Tony,我说的是,“它们似乎都是随着我改变
迭代次数
”而线性扩展的,这意味着当我尝试将代码中的
迭代次数
的值加倍时,所有计时结果也会加倍。我想我应该更清楚,并将我的结果包含在不同的迭代值中。我想我没有这么做是因为我不想让评论变得杂乱无章(我不记得我两年前的推理)。但我相信这是测试这些操作运行时的有效方法。(在下一个注释中继续)如果总时间与执行操作的次数成线性比例,则必须意味着操作以恒定时间运行。例如,如果我在迭代次数=10的情况下运行此测试,推送测试耗时10毫秒,这意味着每次推送平均耗时1毫秒。如果我在迭代次数=100的情况下运行此测试,推送测试耗时100毫秒,这意味着每次推送平均耗时1毫秒。这意味着
push
的运行时相对于数组的长度是恒定的,因为数组的平均长度与迭代次数成线性比例。