From: "mame (Yusuke Endoh) via ruby-core" <ruby-core@ml.ruby-lang.org>
To: ruby-core@ml.ruby-lang.org
Cc: "mame (Yusuke Endoh)" <noreply@ruby-lang.org>
Subject: [ruby-core:121922] [Ruby Feature#21274] Show performance warnings for easily avoidable unnecessary implicit splat allocations
Date: Fri, 09 May 2025 03:18:29 +0000 (UTC) [thread overview]
Message-ID: <redmine.journal-113030.20250509031829.1604@ruby-lang.org> (raw)
In-Reply-To: <redmine.issue-21274.20250418182622.1604@ruby-lang.org>
Issue #21274 has been updated by mame (Yusuke Endoh).
This was discussed at the dev meeting, but @matz was negative about adding this warning. He prefers fluent code over performance, so from Ruby's perspective, he did not want to encourage rewriting:
```ruby
order!(argv, **keywords, &nonopts.method(:<<))
```
to:
```ruby
method = nonopts.method(:<<)
order!(argv, **keywords, &method)
```
----------------------------------------
Feature #21274: Show performance warnings for easily avoidable unnecessary implicit splat allocations
https://bugs.ruby-lang.org/issues/21274#change-113030
* Author: jeremyevans0 (Jeremy Evans)
* Status: Open
----------------------------------------
In Ruby 3.4, I made many changes to reduce implicit allocations (mostly in method calling). There are still a few cases where Ruby must allocate an array for a positional splat, or a hash for a keyword splat. Some of these allocations are unavoidable, but in other cases, while Ruby cannot avoid the allocation, it is easy for a user to make a small change to their code to avoid the allocation. One example of this is when Ruby allocates to avoid an evaluation order issue. For example:
```ruby
def kw = nil
ary = []
m(*ary, kw:)
```
Ruby allocates an array for `*ary`, even though it does not need to, because `kw` is a method call, and the method call could potentially modify `ary` (it doesn't in this example, but Ruby's compiler cannot assume that, as the method may be overridden later). It is simple to avoid the allocation by using a local variable:
```ruby
def kw = nil
ary = []
kw = self.kw
m(*ary, kw:)
```
To make it easier for users to find and avoid these unnecessary implicit allocations, I would like to add a performance warning in cases where Ruby allocates solely to avoid an evaluation order issue.
I've submitted a pull request to implement this: https://github.com/ruby/ruby/pull/13135
The current warning messages in the pull request are quite verbose:
```
$ ruby -W:performance -e 'def kw; {} end; a = []; p(*a, **kw)'
-e: warning: This method call implicitly allocates a potentially unnecessary
array for the positional splat, because a keyword, keyword splat, or block pass
expression could cause an evaluation order issue if an array is not allocated
for the positional splat. You can avoid this allocation by assigning the related
keyword, keyword splat, or block pass expression to a local variable and using
that local variable.
$ ruby -W:performance -e 'def b; ->{} end; h = {}; p(**h, &b)'
-e: warning: This method call implicitly allocates a potentially unnecessary
hash for the keyword splat, because the block pass expression could cause an
evaluation order issue if a hash is not allocated for the keyword splat. You
can avoid this allocation by assigning the block pass expression to a local
variable, and using that local variable.
```
It may be desirable to shorten these messages, so I would appreciate suggestions.
--
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/
prev parent reply other threads:[~2025-05-09 3:19 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-04-18 18:26 [ruby-core:121686] " jeremyevans0 (Jeremy Evans) via ruby-core
2025-04-20 10:46 ` [ruby-core:121693] " jeremyevans0 (Jeremy Evans) via ruby-core
2025-05-08 3:06 ` [ruby-core:121892] " Dan0042 (Daniel DeLorme) via ruby-core
2025-05-08 3:25 ` [ruby-core:121893] " jeremyevans0 (Jeremy Evans) via ruby-core
2025-05-08 3:51 ` [ruby-core:121894] " Dan0042 (Daniel DeLorme) via ruby-core
2025-05-09 3:18 ` mame (Yusuke Endoh) via ruby-core [this message]
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-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=redmine.journal-113030.20250509031829.1604@ruby-lang.org \
--to=ruby-core@ml.ruby-lang.org \
--cc=noreply@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 NNTP newsgroup(s).