ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
* [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).