Issue #22134 has been updated by nobu (Nobuyoshi Nakada). Measurements used the same Ruby development build on macOS arm64, with JIT disabled. The following are medians of seven samples, in nanoseconds per call: | Arguments | Existing approach | `rb_lookup_kwargs` | Speedup | |------------------------------------------|------------------:|-------------------:|--------:| | One keyword | 67.4 | 54.3 | 1.24x | | One keyword via a frozen hash splat | 64.3 | 47.6 | 1.35x | | Four keywords | 121.1 | 106.6 | 1.14x | | Sixteen keywords via a frozen hash splat | 286.5 | 253.0 | 1.13x | ---------------------------------------- Feature #22134: Faster rb_scan_args() for keyword args (optimization) https://bugs.ruby-lang.org/issues/22134#change-118841 * Author: luke-gru (Luke Gruber) * Status: Open ---------------------------------------- ## Motivation When using the `rb_scan_args()` API, often we want to find a value for a given keyword argument. In order to do this, we call `rb_scan_args()` like so: ```c VALUE str; VALUE kwargs; VALUE example; rb_scan_args(argc, argv, "1:", &str, &kwargs); // duplicates the kwargs hash in argv if (!NIL_P(kwargs)) rb_get_kwargs(kwargs, &id_example, 0, 1, &example); // mutates the duplicated kwargs hash to retrieve `example:` ``` This duplicates the keyword args hash given in `argv`. It would be nice to be able to grab a direct reference to the keyword hash and to have a variant of `rb_get_kwargs()` that didn't mutate the passed in hash. ## Proposal Add a new valid format character for `rb_scan_args()`: ```c VALUE str; VALUE kwargs; VALUE example; rb_scan_args(argc, argv, "1:^", &str, &kwargs); // access kwargs directly from argv if (!NIL_P(kwargs)) rb_get_kwargs_const(kwargs, &id_example, 0, 1, &example); // don't mutate the passed kwargs hash ``` This '^' character would only be valid after a ":'. I have a [pull request](https://github.com/ruby/ruby/pull/17558) available for anyone that is interested. Thank you! -- https://bugs.ruby-lang.org/