ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
From: eregontp@gmail.com
To: ruby-core@ruby-lang.org
Subject: [ruby-core:95931] [Ruby master Misc#16188] What are the performance implications of the new keyword arguments in 2.7 and 3.0?
Date: Sun, 24 Nov 2019 23:04:29 +0000 (UTC)	[thread overview]
Message-ID: <redmine.journal-82771.20191124230428.205918b17227eb13@ruby-lang.org> (raw)
In-Reply-To: redmine.issue-16188.20190929182743@ruby-lang.org

Issue #16188 has been updated by Eregon (Benoit Daloze).


jeremyevans0 (Jeremy Evans) wrote:
> Comparing 2.6 to 2.7 is irrelevant in regards to the discussion of the effect of `ruby2_keywords`.  There are many other changes between 2.6 and 2.7 that have a much larger effect than `ruby2_keywords`.

Which other changes would affect calls like `req(*arr)`?
AFAIK, there is no change for that in 2.7 except `ruby2_keywords`, is it?

> If you want to measure  the effect of `ruby2_keywords`, you need to benchmark the master branch against the master branch with the removal of `ruby2_keywords`, as I did in an earlier comment, and as your TruffleRuby benchmark did.

I'm concerned your diff above still keeps some overhead, e.g., there are still references to the `ruby2_keywords` flag.

> Considering the percentage of calls using splats without keyword splats compared to all other calls,

How much do you think is that percentage? Right now I would expect far more `*args` than `*args, **kwargs`.

> it seems unlikely this change will have a significant effect in a real world benchmark on TruffleRuby.

I think it can actually, every `foo(*args)` call, typically used for delegating arguments to another method is can be up to ~11% slower.
Some gems use `foo(*args)` quite often.
Typically, `method_missing` uses it too, and `method_missing` can be performance-sensitive (https://twitter.com/headius/status/1197972352488767489).

----------------------------------------
Misc #16188: What are the performance implications of the new keyword arguments in 2.7 and 3.0?
https://bugs.ruby-lang.org/issues/16188#change-82771

* Author: Eregon (Benoit Daloze)
* Status: Open
* Priority: Normal
* Assignee: jeremyevans0 (Jeremy Evans)
----------------------------------------
In #14183, keyword arguments became further separated from positional arguments.

Contrary to the original design though, keyword and positional arguments are not fully separated for methods not accepting keyword arguments.
Example: `foo(key: :value)` will `def foo(hash)` will pass a positional argument.
This is of course better for compatibility, but I wonder what are the performance implications.

The block argument is completely separate in all versions, so no need to concern ourselves about that.

In Ruby <= 2.6:
* The caller never needs to know about the callee's arguments, it can just take all arguments and pass them as an array.
  The last argument might be used to extract keyword, but this is all done at the callee side.
* Splitting kwargs composed of Symbol and non-Symbol keys can be fairly expensive, but it is a rare occurrence.
  If inlining the callee and kwargs are all passed as a literal Hash at the call site, there shouldn't be any overhead compared to positional arguments once JIT'ed.

In Ruby 2.7:
* The caller needs to pass positional and keyword arguments separately, at least when calling a method accepting kwargs.
  But, if it calls a methods not accepting kwargs, then the "kwargs" (e.g. `foo(key: :value)`) should be treated just like a final Hash positional argument.
* (If we had complete separation, then we could always pass positional and keyword arguments separately, so the caller could once again ignore the callee)

How is the logic implemented in MRI for 2.7?

Specializing the caller for a given callee is a well-known technique.
However, it becomes more difficult if different methods are called from the same callsite (polymorphic call), especially if one accepts kwargs and another does not.
In that case, I think we will see a performance cost to this approach, by having to pass arguments differently based on the method to be called.

What about delegation using `ruby2_keywords`?
Which checks does that add (compared to 2.6) in the merged approach with the Hash flag?



-- 
https://bugs.ruby-lang.org/

  parent reply	other threads:[~2019-11-24 23:04 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <redmine.issue-16188.20190929182743@ruby-lang.org>
2019-09-29 18:27 ` [ruby-core:95148] [Ruby master Misc#16188] What are the performance implications of the new keyword arguments in 2.7 and 3.0? eregontp
2019-09-29 21:01 ` [ruby-core:95151] " merch-redmine
2019-10-15  7:13 ` [ruby-core:95327] " eregontp
2019-10-15 18:42 ` [ruby-core:95343] " merch-redmine
2019-10-22 21:42 ` [ruby-core:95481] " eregontp
2019-10-23  0:01 ` [ruby-core:95485] " nouriyouri
2019-10-23  2:50 ` [ruby-core:95487] " merch-redmine
2019-10-23 11:35 ` [ruby-core:95500] " mame
2019-10-23 16:05 ` [ruby-core:95504] " eregontp
2019-10-24 22:46 ` [ruby-core:95535] " merch-redmine
2019-10-27 10:41 ` [ruby-core:95569] " eregontp
2019-11-24 20:54 ` [ruby-core:95925] " eregontp
2019-11-24 21:56 ` [ruby-core:95926] " eregontp
2019-11-24 22:38 ` [ruby-core:95927] " eregontp
2019-11-24 22:41 ` [ruby-core:95928] " merch-redmine
2019-11-24 22:57 ` [ruby-core:95930] " merch-redmine
2019-11-24 23:04 ` eregontp [this message]
2019-11-25  0:00 ` [ruby-core:95933] " eregontp
2019-11-25  0:22 ` [ruby-core:95934] " eregontp
2019-11-25  2:42 ` [ruby-core:95936] " merch-redmine
2019-11-27 15:38 ` [ruby-core:95986] " eregontp
2019-11-27 15:49 ` [ruby-core:95988] " eregontp
2019-11-27 15:59 ` [ruby-core:95989] " eregontp
2019-11-27 16:19 ` [ruby-core:95991] " merch-redmine
2019-11-27 16:45 ` [ruby-core:95992] " eregontp

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.ruby-lang.org/en/community/mailing-lists/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=redmine.journal-82771.20191124230428.205918b17227eb13@ruby-lang.org \
    --to=ruby-core@ruby-lang.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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 read-only IMAP folder(s) and NNTP newsgroup(s).