From: headius@... Date: 2015-12-28T00:13:54+00:00 Subject: [ruby-core:72530] [Ruby trunk - Feature #11339] [PATCH] io.c: avoid kwarg parsing in C API Issue #11339 has been updated by Charles Nutter. Eric Wong wrote: > Using globals or TLS would introduce subtle reentrancy problems > when calls are nested. I don't want to create more C-APIs > we need to support long-term, either. The global would only be used between the runtime making a call with keyword arguments and the consumption of those arguments for variable initialization in a C method. There's no nesting of calls, and once the C method has consumed the values in the global (i.e. immediately before doing anything else), it is not touched until the next call with keywords from Ruby to C. > JRuby doesn't use our current prelude.rb, I hope. We use parts of it, to stay in alignment with the load order of things like RubyGems and did_you_mean. We won't use the IO parts. The socket changes are in socket.rb, which is part of stdlib and we *do* use it. I'll have to maintain another patch to remove this stuff. > Fwiw, I like the Rubinius philosophy of using Ruby as much as > possible a lot and tried to contribute there back in the day. Yes, except that this doesn't buy anything because 99% of the logic of these methods still lives within C code. If you were also moving the body of these nonblock methods into Ruby, I'd see some value. You've removed a couple lines of C and added a couple lines of Ruby. And now there's going to be an extra method in stack traces and an extra Ruby frame allocated for every call. ---------------------------------------- Feature #11339: [PATCH] io.c: avoid kwarg parsing in C API https://bugs.ruby-lang.org/issues/11339#change-55795 * Author: Eric Wong * Status: Closed * Priority: Normal * Assignee: ---------------------------------------- ~~~ rb_scan_args and hash lookups for kwargs in the C API are clumsy and slow. Instead of improving the C API for performance, use Ruby instead :) Implement IO#read_nonblock and IO#write_nonblock in prelude.rb to avoid argument parsing via rb_scan_args and hash lookups. This speeds up IO#write_nonblock and IO#read_nonblock benchmarks in both cases, including the original non-idiomatic case where the `exception: false' hash is pre-allocated to avoid GC pressure. Now, writing the kwargs in natural, idiomatic Ruby is fastest. I've added the noex2 benchmark to show this. target 0: a (ruby 2.3.0dev (2015-07-08 trunk 51190) [x86_64-linux]) at "a/ruby" target 1: b (ruby 2.3.0dev (2015-07-08 nonblock-kwarg 51190) [x86_64-linux]) at "b/ruby" ----------------------------------------------------------- raw data: [["io_nonblock_noex", [[2.5436805468052626, 2.5724728293716908, 2.4915440678596497], [2.478000810369849, 2.4285155069082975, 2.462410459294915]]], ["io_nonblock_noex2", [[3.012514788657427, 3.034533655270934, 2.9972082190215588], [2.135501991957426, 2.146781364455819, 2.0429874528199434]]]] Elapsed time: 30.348340944 (sec) ----------------------------------------------------------- benchmark results: minimum results in each 3 measurements. Execution time (sec) name a b io_nonblock_noex 2.492 2.429 io_nonblock_noex2 2.997 2.043 Speedup ratio: compare with the result of `a' (greater is better) name b io_nonblock_noex 1.026 io_nonblock_noex2 1.467 Note: I plan to followup commits for other *_nonblock methods Eventually, I even wish to deprecate rb_scan_args :D For what it's worth, I'm more excited about this change than usual and hope to use prelude.rb more. ~~~ ---Files-------------------------------- 0001-io.c-avoid-kwarg-parsing-in-C-API.patch (6.88 KB) -- https://bugs.ruby-lang.org/ Unsubscribe: