* [ruby-core:98968] [Ruby master Feature#16993] Sets: from hash keys using Hash#key_set
@ 2020-06-26 20:31 marcandre-ruby-core
2020-06-27 1:55 ` [ruby-core:98971] " sawadatsuyoshi
` (8 more replies)
0 siblings, 9 replies; 10+ messages in thread
From: marcandre-ruby-core @ 2020-06-26 20:31 UTC (permalink / raw)
To: ruby-core
Issue #16993 has been reported by marcandre (Marc-Andre Lafortune).
----------------------------------------
Feature #16993: Sets: from hash keys using Hash#key_set
https://bugs.ruby-lang.org/issues/16993
* Author: marcandre (Marc-Andre Lafortune)
* Status: Open
* Priority: Normal
----------------------------------------
To create a set from hash keys currently implies a temporary array for all keys, rehashing all those keys and rebuilding a hash. Instead, the hash could be copied and its values set to `true`.
```ruby
h = {a: 1}
# Now:
Set.new(h.keys) # => Set[:a]
# After
h.key_set # => Set[:a], efficiently.
```
--
https://bugs.ruby-lang.org/
^ permalink raw reply [flat|nested] 10+ messages in thread
* [ruby-core:98971] [Ruby master Feature#16993] Sets: from hash keys using Hash#key_set
2020-06-26 20:31 [ruby-core:98968] [Ruby master Feature#16993] Sets: from hash keys using Hash#key_set marcandre-ruby-core
@ 2020-06-27 1:55 ` sawadatsuyoshi
2020-06-27 5:44 ` [ruby-core:98977] " marcandre-ruby-core
` (7 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: sawadatsuyoshi @ 2020-06-27 1:55 UTC (permalink / raw)
To: ruby-core
Issue #16993 has been updated by sawa (Tsuyoshi Sawada).
Would
```ruby
Set.new(h.each_key)
```
not work?
----------------------------------------
Feature #16993: Sets: from hash keys using Hash#key_set
https://bugs.ruby-lang.org/issues/16993#change-86352
* Author: marcandre (Marc-Andre Lafortune)
* Status: Open
* Priority: Normal
----------------------------------------
To create a set from hash keys currently implies a temporary array for all keys, rehashing all those keys and rebuilding a hash. Instead, the hash could be copied and its values set to `true`.
```ruby
h = {a: 1}
# Now:
Set.new(h.keys) # => Set[:a]
# After
h.key_set # => Set[:a], efficiently.
```
--
https://bugs.ruby-lang.org/
^ permalink raw reply [flat|nested] 10+ messages in thread
* [ruby-core:98977] [Ruby master Feature#16993] Sets: from hash keys using Hash#key_set
2020-06-26 20:31 [ruby-core:98968] [Ruby master Feature#16993] Sets: from hash keys using Hash#key_set marcandre-ruby-core
2020-06-27 1:55 ` [ruby-core:98971] " sawadatsuyoshi
@ 2020-06-27 5:44 ` marcandre-ruby-core
2025-02-14 15:42 ` [ruby-core:121050] " greggzst (Grzegorz Jakubiak) via ruby-core
` (6 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: marcandre-ruby-core @ 2020-06-27 5:44 UTC (permalink / raw)
To: ruby-core
Issue #16993 has been updated by marcandre (Marc-Andre Lafortune).
sawa (Tsuyoshi Sawada) wrote in #note-2:
> Would
>
> ```ruby
> Set.new(h.each_key)
> ```
>
> not work?
It will definitely work, but it will be the same as `Set.new(h.keys)` (a bit slower because enumerator is a bit slow). It still iterates on the keys, and add them to the new hash.
Here's a comparison:
```
# frozen_string_literal: true
require 'set'
require 'benchmark/ips'
class Hash
def key_set
s = Set.new
s.instance_variable_set(:@hash, transform_values { true })
s
end
end
size = 50
h = (1..size).to_h { |i| ['x' * i, nil] }
Benchmark.ips do |x|
x.report("key_set") { h.key_set }
x.report("keys") { Set.new(h.keys) }
x.report("new(each_key)") { Set.new(h.each_key) }
x.report("each_key{}") { h2 = {}; h.each_key {|k| h2[k] = true} ; h2 }
```
The last example builds a Hash, not a Set, but it is to show that you can not be quicker than that if you rehash the keys.
I get these results:
```
Calculating -------------------------------------
key_set 244.549k (± 7.4%) i/s - 1.219M in 5.017876s
keys 82.661k (± 2.3%) i/s - 417.400k in 5.052408s
new(each_key) 75.002k (± 5.0%) i/s - 377.400k in 5.045102s
each_key{} 114.757k (± 3.8%) i/s - 582.000k in 5.079700s
```
If you increase the `size`, the ratio will be bigger.
A builtin `keyset` would be even faster, since it would avoid calling the block `{ true }`; yielding is not super fast in Ruby.
----------------------------------------
Feature #16993: Sets: from hash keys using Hash#key_set
https://bugs.ruby-lang.org/issues/16993#change-86358
* Author: marcandre (Marc-Andre Lafortune)
* Status: Open
* Priority: Normal
----------------------------------------
To create a set from hash keys currently implies a temporary array for all keys, rehashing all those keys and rebuilding a hash. Instead, the hash could be copied and its values set to `true`.
```ruby
h = {a: 1}
# Now:
Set.new(h.keys) # => Set[:a]
# After
h.key_set # => Set[:a], efficiently.
```
--
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>
^ permalink raw reply [flat|nested] 10+ messages in thread
* [ruby-core:121050] [Ruby master Feature#16993] Sets: from hash keys using Hash#key_set
2020-06-26 20:31 [ruby-core:98968] [Ruby master Feature#16993] Sets: from hash keys using Hash#key_set marcandre-ruby-core
2020-06-27 1:55 ` [ruby-core:98971] " sawadatsuyoshi
2020-06-27 5:44 ` [ruby-core:98977] " marcandre-ruby-core
@ 2025-02-14 15:42 ` greggzst (Grzegorz Jakubiak) via ruby-core
2025-02-15 4:07 ` [ruby-core:121065] " nobu (Nobuyoshi Nakada) via ruby-core
` (5 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: greggzst (Grzegorz Jakubiak) via ruby-core @ 2025-02-14 15:42 UTC (permalink / raw)
To: ruby-core; +Cc: greggzst (Grzegorz Jakubiak)
Issue #16993 has been updated by greggzst (Grzegorz Jakubiak).
I opened a PR to add this functionality https://github.com/ruby/ruby/pull/12750
----------------------------------------
Feature #16993: Sets: from hash keys using Hash#key_set
https://bugs.ruby-lang.org/issues/16993#change-111962
* Author: marcandre (Marc-Andre Lafortune)
* Status: Open
----------------------------------------
To create a set from hash keys currently implies a temporary array for all keys, rehashing all those keys and rebuilding a hash. Instead, the hash could be copied and its values set to `true`.
```ruby
h = {a: 1}
# Now:
Set.new(h.keys) # => Set[:a]
# After
h.key_set # => Set[:a], efficiently.
```
--
https://bugs.ruby-lang.org/
______________________________________________
ruby-core mailing list -- ruby-core@ml.ruby-lang.org
To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/
^ permalink raw reply [flat|nested] 10+ messages in thread
* [ruby-core:121065] [Ruby master Feature#16993] Sets: from hash keys using Hash#key_set
2020-06-26 20:31 [ruby-core:98968] [Ruby master Feature#16993] Sets: from hash keys using Hash#key_set marcandre-ruby-core
` (2 preceding siblings ...)
2025-02-14 15:42 ` [ruby-core:121050] " greggzst (Grzegorz Jakubiak) via ruby-core
@ 2025-02-15 4:07 ` nobu (Nobuyoshi Nakada) via ruby-core
2025-02-15 16:41 ` [ruby-core:121068] " Dan0042 (Daniel DeLorme) via ruby-core
` (4 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: nobu (Nobuyoshi Nakada) via ruby-core @ 2025-02-15 4:07 UTC (permalink / raw)
To: ruby-core; +Cc: nobu (Nobuyoshi Nakada)
Issue #16993 has been updated by nobu (Nobuyoshi Nakada).
This kind of extensions should be done in the corresponding library side, set.rb.
----------------------------------------
Feature #16993: Sets: from hash keys using Hash#key_set
https://bugs.ruby-lang.org/issues/16993#change-111978
* Author: marcandre (Marc-Andre Lafortune)
* Status: Open
----------------------------------------
To create a set from hash keys currently implies a temporary array for all keys, rehashing all those keys and rebuilding a hash. Instead, the hash could be copied and its values set to `true`.
```ruby
h = {a: 1}
# Now:
Set.new(h.keys) # => Set[:a]
# After
h.key_set # => Set[:a], efficiently.
```
--
https://bugs.ruby-lang.org/
______________________________________________
ruby-core mailing list -- ruby-core@ml.ruby-lang.org
To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/
^ permalink raw reply [flat|nested] 10+ messages in thread
* [ruby-core:121068] [Ruby master Feature#16993] Sets: from hash keys using Hash#key_set
2020-06-26 20:31 [ruby-core:98968] [Ruby master Feature#16993] Sets: from hash keys using Hash#key_set marcandre-ruby-core
` (3 preceding siblings ...)
2025-02-15 4:07 ` [ruby-core:121065] " nobu (Nobuyoshi Nakada) via ruby-core
@ 2025-02-15 16:41 ` Dan0042 (Daniel DeLorme) via ruby-core
2025-02-15 22:53 ` [ruby-core:121072] " greggzst (Grzegorz Jakubiak) via ruby-core
` (3 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Dan0042 (Daniel DeLorme) via ruby-core @ 2025-02-15 16:41 UTC (permalink / raw)
To: ruby-core; +Cc: Dan0042 (Daniel DeLorme)
Issue #16993 has been updated by Dan0042 (Daniel DeLorme).
I like the concept but I'm going to bikeshed the naming: by itself "key_set" is unclear if you don't already know what it does. It sounds like the purpose is to set a key (like instance_variable_set). I'd prefer something a bit more descriptive like "keys_to_set"
----------------------------------------
Feature #16993: Sets: from hash keys using Hash#key_set
https://bugs.ruby-lang.org/issues/16993#change-111984
* Author: marcandre (Marc-Andre Lafortune)
* Status: Open
----------------------------------------
To create a set from hash keys currently implies a temporary array for all keys, rehashing all those keys and rebuilding a hash. Instead, the hash could be copied and its values set to `true`.
```ruby
h = {a: 1}
# Now:
Set.new(h.keys) # => Set[:a]
# After
h.key_set # => Set[:a], efficiently.
```
--
https://bugs.ruby-lang.org/
______________________________________________
ruby-core mailing list -- ruby-core@ml.ruby-lang.org
To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/
^ permalink raw reply [flat|nested] 10+ messages in thread
* [ruby-core:121072] [Ruby master Feature#16993] Sets: from hash keys using Hash#key_set
2020-06-26 20:31 [ruby-core:98968] [Ruby master Feature#16993] Sets: from hash keys using Hash#key_set marcandre-ruby-core
` (4 preceding siblings ...)
2025-02-15 16:41 ` [ruby-core:121068] " Dan0042 (Daniel DeLorme) via ruby-core
@ 2025-02-15 22:53 ` greggzst (Grzegorz Jakubiak) via ruby-core
2025-03-13 11:16 ` [ruby-core:121327] " mame (Yusuke Endoh) via ruby-core
` (2 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: greggzst (Grzegorz Jakubiak) via ruby-core @ 2025-02-15 22:53 UTC (permalink / raw)
To: ruby-core; +Cc: greggzst (Grzegorz Jakubiak)
Issue #16993 has been updated by greggzst (Grzegorz Jakubiak).
nobu (Nobuyoshi Nakada) wrote in #note-5:
> This kind of extensions should be done in the corresponding library side, set.rb.
Thanks for pointing that out. Here's the PR https://github.com/ruby/set/pull/40
Dan0042 (Daniel DeLorme) wrote in #note-6:
> I like the concept but I'm going to bikeshed the naming: by itself "key_set" is unclear if you don't already know what it does. It sounds like the purpose is to set a key (like instance_variable_set). I'd prefer something a bit more descriptive like "keys_to_set"
Good point I addressed that
----------------------------------------
Feature #16993: Sets: from hash keys using Hash#key_set
https://bugs.ruby-lang.org/issues/16993#change-111989
* Author: marcandre (Marc-Andre Lafortune)
* Status: Open
----------------------------------------
To create a set from hash keys currently implies a temporary array for all keys, rehashing all those keys and rebuilding a hash. Instead, the hash could be copied and its values set to `true`.
```ruby
h = {a: 1}
# Now:
Set.new(h.keys) # => Set[:a]
# After
h.key_set # => Set[:a], efficiently.
```
--
https://bugs.ruby-lang.org/
______________________________________________
ruby-core mailing list -- ruby-core@ml.ruby-lang.org
To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/
^ permalink raw reply [flat|nested] 10+ messages in thread
* [ruby-core:121327] [Ruby master Feature#16993] Sets: from hash keys using Hash#key_set
2020-06-26 20:31 [ruby-core:98968] [Ruby master Feature#16993] Sets: from hash keys using Hash#key_set marcandre-ruby-core
` (5 preceding siblings ...)
2025-02-15 22:53 ` [ruby-core:121072] " greggzst (Grzegorz Jakubiak) via ruby-core
@ 2025-03-13 11:16 ` mame (Yusuke Endoh) via ruby-core
2025-04-08 5:54 ` [ruby-core:121570] [Ruby " mame (Yusuke Endoh) via ruby-core
2025-04-08 13:00 ` [ruby-core:121587] " Dan0042 (Daniel DeLorme) via ruby-core
8 siblings, 0 replies; 10+ messages in thread
From: mame (Yusuke Endoh) via ruby-core @ 2025-03-13 11:16 UTC (permalink / raw)
To: ruby-core; +Cc: mame (Yusuke Endoh)
Issue #16993 has been updated by mame (Yusuke Endoh).
This was discussed at the dev meeting. @matz wanted to hear more about the use cases for this method first.
Also, since Set is currently in a halfway state where it is not fully built-in, a built-in `Hash#key_set` might require a special hack like `Enumerable#to_set`.
https://github.com/ruby/ruby/blob/7c88cbb4a6c486348c44be24941f17ef8be6b329/prelude.rb#L34
@akr pointed out the possible consistency issue of `Hash#compare_by_identity`. Since `Hash#transform_values` keeps this `compare_by_identity` flag, the proposed patch will assign a Hash with `compare_by_identity` flag to `@hash` in Set. We will need to review it carefully to make sure it does not break the implicit assumptions of `set.rb`.
----------------------------------------
Feature #16993: Sets: from hash keys using Hash#key_set
https://bugs.ruby-lang.org/issues/16993#change-112294
* Author: marcandre (Marc-Andre Lafortune)
* Status: Open
----------------------------------------
To create a set from hash keys currently implies a temporary array for all keys, rehashing all those keys and rebuilding a hash. Instead, the hash could be copied and its values set to `true`.
```ruby
h = {a: 1}
# Now:
Set.new(h.keys) # => Set[:a]
# After
h.key_set # => Set[:a], efficiently.
```
--
https://bugs.ruby-lang.org/
______________________________________________
ruby-core mailing list -- ruby-core@ml.ruby-lang.org
To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/
^ permalink raw reply [flat|nested] 10+ messages in thread
* [ruby-core:121570] [Ruby Feature#16993] Sets: from hash keys using Hash#key_set
2020-06-26 20:31 [ruby-core:98968] [Ruby master Feature#16993] Sets: from hash keys using Hash#key_set marcandre-ruby-core
` (6 preceding siblings ...)
2025-03-13 11:16 ` [ruby-core:121327] " mame (Yusuke Endoh) via ruby-core
@ 2025-04-08 5:54 ` mame (Yusuke Endoh) via ruby-core
2025-04-08 13:00 ` [ruby-core:121587] " Dan0042 (Daniel DeLorme) via ruby-core
8 siblings, 0 replies; 10+ messages in thread
From: mame (Yusuke Endoh) via ruby-core @ 2025-04-08 5:54 UTC (permalink / raw)
To: ruby-core; +Cc: mame (Yusuke Endoh)
Issue #16993 has been updated by mame (Yusuke Endoh).
Given the convention of deriving methods such as `key_set` from `keys`, where the former returns a set instead of an array, one might expect a corresponding derivation like `Kernel#instance_variable_set` for `Kernel#instance_variables`. Unfortunately, this would conflict with an existing method name.
----------------------------------------
Feature #16993: Sets: from hash keys using Hash#key_set
https://bugs.ruby-lang.org/issues/16993#change-112627
* Author: marcandre (Marc-Andre Lafortune)
* Status: Open
----------------------------------------
To create a set from hash keys currently implies a temporary array for all keys, rehashing all those keys and rebuilding a hash. Instead, the hash could be copied and its values set to `true`.
```ruby
h = {a: 1}
# Now:
Set.new(h.keys) # => Set[:a]
# After
h.key_set # => Set[:a], efficiently.
```
--
https://bugs.ruby-lang.org/
______________________________________________
ruby-core mailing list -- ruby-core@ml.ruby-lang.org
To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/
^ permalink raw reply [flat|nested] 10+ messages in thread
* [ruby-core:121587] [Ruby Feature#16993] Sets: from hash keys using Hash#key_set
2020-06-26 20:31 [ruby-core:98968] [Ruby master Feature#16993] Sets: from hash keys using Hash#key_set marcandre-ruby-core
` (7 preceding siblings ...)
2025-04-08 5:54 ` [ruby-core:121570] [Ruby " mame (Yusuke Endoh) via ruby-core
@ 2025-04-08 13:00 ` Dan0042 (Daniel DeLorme) via ruby-core
8 siblings, 0 replies; 10+ messages in thread
From: Dan0042 (Daniel DeLorme) via ruby-core @ 2025-04-08 13:00 UTC (permalink / raw)
To: ruby-core; +Cc: Dan0042 (Daniel DeLorme)
Issue #16993 has been updated by Dan0042 (Daniel DeLorme).
mame (Yusuke Endoh) wrote in #note-9:
> Given the convention of deriving methods such as `key_set` from `keys`, where the former returns a set instead of an array, one might expect a corresponding derivation like `Kernel#instance_variable_set` for `Kernel#instance_variables`. Unfortunately, this would conflict with an existing method name.
In https://github.com/ruby/set/pull/40 the name was changed to #keys_to_set, so this comment doesn't apply anymore.
Then again I wish all optimizations like this could be implemented at the VM level, so that `hash.keys.to_set` would automatically be efficient rather than having to explicitly use the efficient version #keys_to_set.
----------------------------------------
Feature #16993: Sets: from hash keys using Hash#key_set
https://bugs.ruby-lang.org/issues/16993#change-112642
* Author: marcandre (Marc-Andre Lafortune)
* Status: Open
----------------------------------------
To create a set from hash keys currently implies a temporary array for all keys, rehashing all those keys and rebuilding a hash. Instead, the hash could be copied and its values set to `true`.
```ruby
h = {a: 1}
# Now:
Set.new(h.keys) # => Set[:a]
# After
h.key_set # => Set[:a], efficiently.
```
--
https://bugs.ruby-lang.org/
______________________________________________
ruby-core mailing list -- ruby-core@ml.ruby-lang.org
To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2025-04-08 13:01 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-26 20:31 [ruby-core:98968] [Ruby master Feature#16993] Sets: from hash keys using Hash#key_set marcandre-ruby-core
2020-06-27 1:55 ` [ruby-core:98971] " sawadatsuyoshi
2020-06-27 5:44 ` [ruby-core:98977] " marcandre-ruby-core
2025-02-14 15:42 ` [ruby-core:121050] " greggzst (Grzegorz Jakubiak) via ruby-core
2025-02-15 4:07 ` [ruby-core:121065] " nobu (Nobuyoshi Nakada) via ruby-core
2025-02-15 16:41 ` [ruby-core:121068] " Dan0042 (Daniel DeLorme) via ruby-core
2025-02-15 22:53 ` [ruby-core:121072] " greggzst (Grzegorz Jakubiak) via ruby-core
2025-03-13 11:16 ` [ruby-core:121327] " mame (Yusuke Endoh) via ruby-core
2025-04-08 5:54 ` [ruby-core:121570] [Ruby " mame (Yusuke Endoh) via ruby-core
2025-04-08 13:00 ` [ruby-core:121587] " Dan0042 (Daniel DeLorme) via ruby-core
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).