我需要一种非常快速的方法来确定数组是否仅包含值为9
的整数。这是我目前的解决方案:
input = [9,9,9,9,9,9,9,9,9,9,9,9]
input.uniq == [9]
你能更快地完成吗?
答案 0 :(得分:31)
require 'benchmark'
n = 50000
Benchmark.bm do |x|
x.report "uniq " do
n.times do
input = [9,9,9,9,9,9,9,9,9,9,9,9]
input.uniq == [9]
end
end
x.report "delete" do
n.times do
input = [9,9,9,9,9,9,9,9,9,9,9,9]
input.delete 9
input == []
end
end
x.report "count " do
n.times do
input = [9,9,9,9,9,9,9,9,9,9,9,9]
input.count(9)==input.size
end
end
x.report "select" do
n.times do
input = [9,9,9,9,9,9,9,9,9,9,9,9]
input.select{|x| x != 9}.empty?
end
end
x.report "detect" do
n.times do
input = [9,9,9,9,9,9,9,9,9,9,9,9]
input.detect { |i| i != 9 }.nil?
end
end
x.report "all? " do
n.times do
input = [9,9,9,9,9,9,9,9,9,9,9,9]
input.all?{|x| x == 9}
end
end
end
它是上述答案和某些我的答案的基准
user system total real
uniq 0.313000 0.000000 0.313000 ( 0.312500)
delete 0.140000 0.000000 0.140000 ( 0.140625)
count 0.079000 0.000000 0.079000 ( 0.078125)
select 0.234000 0.000000 0.234000 ( 0.234375)
detect 0.234000 0.000000 0.234000 ( 0.234375)
all? 0.219000 0.000000 0.219000 ( 0.218750)
如果input = [1]+[9]*9
:
user system total real
uniq 0.328000 0.000000 0.328000 ( 0.328125)
delete 0.188000 0.000000 0.188000 ( 0.203125)
count 0.187000 0.000000 0.187000 ( 0.218750)
select 0.281000 0.016000 0.297000 ( 0.296875)
detect 0.203000 0.000000 0.203000 ( 0.203125)
all? 0.204000 0.000000 0.204000 ( 0.203125)
如果input = [9]*9 + [1]
:
user system total real
uniq 0.313000 0.000000 0.313000 ( 0.328125)
delete 0.187000 0.000000 0.187000 ( 0.187500)
count 0.172000 0.000000 0.172000 ( 0.187500)
select 0.297000 0.000000 0.297000 ( 0.312500)
detect 0.313000 0.000000 0.313000 ( 0.312500)
all? 0.281000 0.000000 0.281000 ( 0.281250)
如果input = [1,2,3,4,5,6,7,8,9]
:
user system total real
uniq 0.407000 0.000000 0.407000 ( 0.406250)
delete 0.125000 0.000000 0.125000 ( 0.125000)
count 0.125000 0.000000 0.125000 ( 0.125000)
select 0.218000 0.000000 0.218000 ( 0.234375)
detect 0.110000 0.000000 0.110000 ( 0.109375)
all? 0.109000 0.000000 0.109000 ( 0.109375)
答案 1 :(得分:16)
您有几个选择:
>> input.count(9)==input.size
=> true
或
>> input.select{|x| x != 9}.empty?
=> true
或您上面的解决方案。
答案 2 :(得分:4)
这会循环数组并在发现非九的时候中断(返回false)。
[9,9,9,9,9,9,9,9,9,9,9,9].all?{|x| x == 9} # => true
答案 3 :(得分:3)
编辑:找到完整的源代码here。支持@nash获取最初的想法。
一旦找到元素,就迭代并返回false!= match。
def all_matches(arr, match)
arr.each do |element|
return false if element != match
end
true
end
使用0到9的2M随机整数,50个循环(n=50
):
user system total real uniq 5.230000 0.010000 5.240000 ( 5.219444) count 2.680000 0.010000 2.690000 ( 2.677923) select 7.580000 0.060000 7.640000 ( 7.634620) detect 0.000000 0.000000 0.000000 ( 0.000068) all? 0.000000 0.000000 0.000000 ( 0.000046) mine 0.000000 0.000000 0.000000 ( 0.000032) delete 5.090000 0.020000 5.110000 ( 5.101290) any? 0.000000 0.000000 0.000000 ( 0.000041)
用于生成数组的代码:
input = []
2000000.times { input << (rand*10).to_i }
使用2M 9(所有 9),50个循环:
user system total real uniq 4.900000 0.000000 4.900000 ( 4.890030) count 0.350000 0.000000 0.350000 ( 0.351340) select 5.400000 0.010000 5.410000 ( 5.393489) detect 6.720000 0.000000 6.720000 ( 6.685539) all? 6.070000 0.000000 6.070000 ( 6.061914) mine 5.510000 0.010000 5.520000 ( 5.500186) delete 1.080000 0.010000 1.090000 ( 1.084125) any? 6.200000 0.000000 6.200000 ( 6.197529)
答案 4 :(得分:0)
我认为你的意思是input.uniq == [9]
,因为你实际上给我的回报是假的。你的意思更快?这段代码需要运行得非常快吗?我想检测更快,因为它将返回匹配测试的第一个元素:
input = [9,9,9,9,9,9,9,9,9,9,9,9]
input.detect { |i| i != 9 }.nil?
答案 5 :(得分:0)
也许是最慢的,但这是我想到的
input = [9,9,9,9,9,9,9,9,9,9,9,9]
!(input.any { |a| a != 9 })
答案 6 :(得分:0)
这是另一个更快的(上面的计数方法仍然是最快的):
arr = [9,9,9,9,9,9,9,9,9,9,9,9]
arr.reject { |i| i==9 }.count == 0
和一个慢一点的人:
arr.inject(:&) == 9
这是'果味'宝石比较:
require 'fruity'
compare do
count { arr.count(9) == arr.size }
uniq { arr.uniq == [9] }
bitwise_and { arr.inject(:&) == 9 }
reject { arr.reject { |i| i==9 }.count == 0 }
end
Running each test 8192 times. Test will take about 3 seconds.
count is faster than reject by 39.99999999999999% ± 10.0%
reject is faster than uniq by 10x ± 1.0
uniq is faster than bit_and by 30.000000000000004% ± 1.0%
答案 7 :(得分:0)
这很有效:
> array = ['apple', 'banana']
> includes = array.uniq.include? 'banana'
> => true
此外,通过扩展,我们可以检查所有值是否相同而不知道它们是什么:
> array = ['apple', 'banana', 'apple']
> all_same_values = (array.uniq.length > 1) ? false : true
> => false