Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

Parallel versus sequential assignment is microbenchmark (not representative) and scales with number of inputs

未关闭
#208 7 条评论 1 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

评估

难度
4/5
预计耗时
3-5 天
新手友好度
42/100
Issue 类型
文档
描述清晰度
基本清楚
活跃度
停滞
技术栈
ruby

调研方向

审查 code/general/assignment.rb 及相关的 README 展示,然后将 benchmark 的声明与此 issue 中的示例和测量结果进行比较。确定是否应移除 benchmark 或为其添加大量注释,并验证最终的文档不再将该比较呈现为具有广泛代表性。

由索引模型根据 Issue 内容生成。

描述

Update: Parallel assignment doesn't allocate unless it's the last statement in a method/proc. There's a benchmark provided below. I'm

I think this benchmark https://github.com/fastruby/fast-ruby/blob/main/code/general/assignment.rb needs to be removed or at least heavily annotated on the readme. It is not representative of real code. In my experience, removing parallel assignments into sequential ones speeds up apps.

One reason is that parallel assignments [can] allocate an intermediate array [if it is the last statement in a method for example], the other is that the benchmark uses MANY assignments and the performance difference seems to scale with assignment numbers. In the wild the most common number is 2.

Also worth noting that by using integers, we're isolating to only the assignment time (mostly) but this distorts the possible impact of the code. If you switch to strings that allocate then the pressure on the GC actually causes sequential assignment to be faster (at least sometimes).

Benchmarks below.

Reasoning

In https://github.com/fastruby/fast-ruby/blob/main/code/general/assignment.rb it states that parallel assignment is much faster than sequential assignment, but if you have only 2 assignments, the difference is negligible:

require 'benchmark/ips'

def fast
  _a, _b= 1, 2
  nil
end

def slow
  _a = 1
  _b = 2
  nil
end

Benchmark.ips do |x|
  x.report('Parallel Assignment')   { fast }
  x.report('Sequential Assignment') { slow }
  x.compare!
end
Warming up --------------------------------------
 Parallel Assignment     1.494M i/100ms
Sequential Assignment
                         1.344M i/100ms
Calculating -------------------------------------
 Parallel Assignment     14.659M (± 4.9%) i/s -     73.229M in   5.007646s
Sequential Assignment
                         15.020M (± 4.0%) i/s -     75.261M in   5.019081s

Comparison:
Sequential Assignment: 15019526.2 i/s
 Parallel Assignment: 14658684.7 i/s - same-ish: difference falls within error

Note that sequential assignment is faster here (but within error). While the parallel assignment is fewer operations, it also introduces an intermediate array that requires an allocation:

$ cat scratch.rb
require 'memory_profiler'
report = MemoryProfiler.report do
  _a, _b = 1, 2
end

report.pretty_print
⛄️ 3.1.2 🚀 /tmp
$ ruby scratch.rb
Total allocated: 40 bytes (1 objects)
Total retained:  40 bytes (1 objects)

allocated memory by gem
-----------------------------------
        40  other

allocated memory by file
-----------------------------------
        40  scratch.rb

allocated memory by location
-----------------------------------
        40  scratch.rb:3

allocated memory by class
-----------------------------------
        40  Array
# ...

[Note that the above only works because the parallel assignment is returned _a, _b = 1, 2; nil does not allocate]

Even in the case of MANY sequential versus parallel assignments, if the function is doing anything non-trivial (such as allocating strings as opposed to using integers which are all singletons, then the effect of the "faster" parallel assignment is pretty much negligible. This run actually has sequential being faster:

require 'benchmark/ips'

def fast
  _a, _b, _c, _d, _e, _f, _g, _h = String.new("1"), String.new("2"), String.new("3"), String.new("4"), String.new("5"), String.new("6"), String.new("7"), String.new("8")
  nil
end

def slow
  _a = String.new("1")
  _b = String.new("2")
  _c = String.new("3")
  _d = String.new("4")
  _e = String.new("5")
  _f = String.new("6")
  _g = String.new("7")
  _h = String.new("8")
  nil
end

Benchmark.ips do |x|
  x.report('Parallel Assignment')   { fast }
  x.report('Sequential Assignment') { slow }
  x.compare!
end
Warming up --------------------------------------
 Parallel Assignment    80.318k i/100ms
Sequential Assignment
                        77.943k i/100ms
Calculating -------------------------------------
 Parallel Assignment    796.245k (± 3.7%) i/s -      4.016M in   5.050973s
Sequential Assignment
                        767.116k (± 5.9%) i/s -      3.897M in   5.099053s

Comparison:
 Parallel Assignment:   796245.3 i/s
Sequential Assignment:   767115.8 i/s - same-ish: difference falls within error

The sequential assignment is also faster here (but within error).

主要语言
Ruby
星标
5.7k
派生
370
PR 合并指标
30 天内没有已合并 PR

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

fastruby/fast-ruby 的其他 Issue

查看 fastruby/fast-ruby 的全部 Issue

相似的 Issue

更多 Ruby Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。