[#105450] [Ruby master Feature#18228] Add a `timeout` option to `IO.copy_stream` — "byroot (Jean Boussier)" <noreply@...>
Issue #18228 has been reported by byroot (Jean Boussier).
11 messages
2021/09/27
[ruby-core:105356] [Ruby master Feature#18181] Introduce Enumerable#min_with_value, max_with_value, and minmax_with_value
From:
"kyanagi (Kouhei Yanagita)" <noreply@...>
Date:
2021-09-21 08:53:02 UTC
List:
ruby-core #105356
Issue #18181 has been updated by kyanagi (Kouhei Yanagita).
`enum.group_by { ... }` holds all of the elements of enum,
so it consumes a lot of memory and is very slow if enum is enormous.
``` ruby
require 'benchmark'
Benchmark.bm(16) do |x|
enum = -1000000..1000000
x.report("group_by") { enum.group_by { |i| i.abs }.min }
x.report("map.min_by") { enum.map { |i| [i.abs, i] }.min_by(&:first) }
x.report("min_with_value") { enum.min_with_value { |i| i.abs } }
x.report("each") { enum.each { |i| i.abs } }
end
```
```
user system total real
group_by 1.238664 0.243779 1.482443 ( 1.483547)
map.min_by 0.721992 0.047738 0.769730 ( 0.770767)
min_with_value 0.236433 0.004105 0.240538 ( 0.240596)
each 0.150815 0.000000 0.150815 ( 0.151704)
```
`#min` and `#min_by` return single element even through there are multiple smallest elements.
There may be cases where it is useful to return multiple elements,
but single element will be enough for most cases.
Writing `elements.first` everytime is a little bit of a pain.
Besides, size of the elements may become very large. (if almost all of the elements are mapped into the same value)
I think `#min_with_value` should return the element as primary (i.e. the element is first, the block's value is second)
because `#min` and `#min_by` return the element.
Additionally, this is similar to the way `#each_with_index` and `#each_with_object` pass their block arguments.
``` ruby
enum.each_with_index do |elem, i| # <- the element is first, the other is second.
end
enum.each_with_object([]) do |elem, obj| # <- the element is first, the other is second.
end
```
Naming issue:
The behavior of this method is described as "The minimum element by the block value and its value".
Based on this, the name will be something like `min_element_by_value_and_value` or `min_element_by_value_with_value` if verbosely named.
Considering the method `#min` which returns the element, the word "element" is thought to be able to omitted.
So I suggest the short name `#min_with_value`. (I think `#min_by_with_value` is also possible.)
The word "with" implies that "min(_element)" and "value" are different objects.
----------------------------------------
Feature #18181: Introduce Enumerable#min_with_value, max_with_value, and minmax_with_value
https://bugs.ruby-lang.org/issues/18181#change-93770
* Author: kyanagi (Kouhei Yanagita)
* Status: Open
* Priority: Normal
----------------------------------------
PR is https://github.com/ruby/ruby/pull/4874
I propose `Enumerable#min_with_value`, `max_with_value` and `minmax_with_value`.
These methods work like this:
``` ruby
%w(abcde fg hijk).min_with_value { |e| e.size } # => ['fg', 2]
%w(abcde fg hijk).max_with_value { |e| e.size } # => ['abcde', 5]
%w(abcde fg hijk).minmax_with_value { |e| e.size } # => [['fg', 2], ['abcde', 5]]
```
Motivation:
When I use `Enumerable#min_by`, I sometimes want to get not only the minimum element
but also the value from the given block.
(e.g.: There are many points. Find the nearest point and get distance to it.)
``` ruby
elem = enum.min_by { |e| foo(e) }
value = foo(elem)
```
This works, but I'd like to avoid writing foo() twice. (Consider a more complex case.)
This can be written without repeated foo() like belows, but it is slightly complicated and needs extra arrays.
``` ruby
value, elem = enum.map { |e| [foo(e), e] }.min_by(&:first)
```
If the size of enum is enormous, it is hard to use intermediate arrays.
`Enumerable#min_with_value` solves this problem.
I think `min_with_value` is the best name I could think of, but any suggestions for better names would be appreciated.
--
https://bugs.ruby-lang.org/
Unsubscribe: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>