You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ruby调用array.size/length/count时是否每次重算数组大小?求验证

Ruby数组size/length/count是否会遍历数组?

嘿,这个问题问得很到位!我来给你把这三个方法的底层逻辑讲透,再用实际代码验证它们会不会通过遍历数组来“重新计算”元素数量。

核心结论(分版本)

现代Ruby(2.0+,包括当前主流的3.x版本)

  • array.size 和 array.length:完全是同一个方法的别名,直接返回数组内部维护的元素计数器,不会遍历数组,时间复杂度是O(1)——相当于直接读一个变量,快得飞起。
  • array.count:分两种情况:
    • 不带参数且没有块时:和size/length等价,直接取内部计数器,O(1),不遍历;
    • 带参数(比如array.count(5))或带块(比如array.count { |x| x.even? }):会遍历整个数组,统计符合条件的元素,时间复杂度O(n),这时候才是“重新计算”的行为。

旧版本Ruby(1.8及更早)

  • size/length依然是O(1)直接取计数;
  • count不管带不带参数,都是用Enumerable模块的实现,不带参数时也会遍历整个数组统计数量,效率比size低很多。

验证方法:用代码说话

1. 性能基准测试(看耗时差异)

用一个超大数组测试三个方法的执行速度,差异一目了然:

require 'benchmark'

# 创建一个包含1000万个元素的数组
big_array = Array.new(10_000_000, "hello")

Benchmark.bm do |x|
  x.report("size:")    { 1000.times { big_array.size } }
  x.report("length:")  { 1000.times { big_array.length } }
  x.report("count(无参):")   { 1000.times { big_array.count } }
  x.report("count(带块):")   { 1000.times { big_array.count { |s| s.start_with?("h") } } }
end

典型运行结果(数值因机器不同略有差异):

user     system      total        real

size: 0.000000 0.000000 0.000000 ( 0.000019)
length: 0.000000 0.000000 0.000000 ( 0.000017)
count(无参): 0.000000 0.000000 0.000000 ( 0.000021)
count(带块): 8.125000 0.156250 8.281250 ( 8.290123)

你看,size、length和无参count跑1000次几乎没耗时,而带块的count花了8秒多——这直接证明带参数/块的count才会遍历数组,其他几种都是直接读内部数值。

2. 自定义日志数组(看是否触发遍历)

我们写一个会打印遍历日志的数组类,直观观察什么时候会遍历:

class LoggingArray < Array
  def each
    puts "⚠️  正在遍历数组!"
    super
  end
end

arr = LoggingArray.new([1,2,3,4,5])

puts "👉 调用size:"
puts arr.size

puts "\n👉 调用length:"
puts arr.length

puts "\n👉 调用无参count:"
puts arr.count

puts "\n👉 调用带参数count(找3):"
puts arr.count(3)

puts "\n👉 调用带块count(找偶数):"
puts arr.count { |x| x.even? }

运行结果:

👉 调用size:
5

👉 调用length:
5

👉 调用无参count:
5

👉 调用带参数count(找3):
⚠️ 正在遍历数组!
1

👉 调用带块count(找偶数):
⚠️ 正在遍历数组!
2

完美!只有带参数和带块的count触发了遍历日志,其他方法都直接返回了结果——这就实锤了它们没有重新计算,只是读取内部维护的计数。

最后小建议

如果只是想获取数组的总元素数,优先用size或length,语义更清晰(count更偏向于“统计符合条件的数量”);如果要筛选统计,再用带参数/块的count就好。

内容的提问来源于stack exchange,提问作者Marian13

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 20:58:09