[#104740] [Ruby master Feature#18057] Introduce Array#average — ggmichaelgo@...

Issue #18057 has been reported by ggmichaelgo (Michael Go).

14 messages 2021/08/02

[#104774] [Ruby master Bug#18061] Execshield test: libruby.so.N.N.N: FAIL: property-note test because no .note.gnu.property section found — jaruga@...

Issue #18061 has been reported by jaruga (Jun Aruga).

48 messages 2021/08/04

[#104780] [Ruby master Bug#18062] Ruby with enabled LTO segfaults during build — v.ondruch@...

Issue #18062 has been reported by vo.x (Vit Ondruch).

30 messages 2021/08/05

[#104831] [Ruby master Bug#18066] Load did_you_mean eve/error_highlight even with --disable-gems — v.ondruch@...

Issue #18066 has been reported by vo.x (Vit Ondruch).

10 messages 2021/08/07

[#104851] [Ruby master Bug#18073] test/ruby/test_jit.rb: failures "error: invalid use of '__builtin_va_arg_pack ()'" on Ruby 2.7.4 on gcc 4.8.5 on RHEL7 — jaruga@...

Issue #18073 has been reported by jaruga (Jun Aruga).

14 messages 2021/08/09

[#104927] [Ruby master Bug#18077] Marshal.dump(closed_io) raises IOError instead of TypeError — "larskanis (Lars Kanis)" <noreply@...>

Issue #18077 has been reported by larskanis (Lars Kanis).

10 messages 2021/08/16

[#104960] [Ruby master Feature#18083] Capture error in ensure block. — "ioquatix (Samuel Williams)" <noreply@...>

Issue #18083 has been reported by ioquatix (Samuel Williams).

32 messages 2021/08/18

[#105021] [Ruby master Misc#18122] DevelopersMeeting20210916Japan — "mame (Yusuke Endoh)" <noreply@...>

Issue #18122 has been reported by mame (Yusuke Endoh).

12 messages 2021/08/20

[#105069] [Ruby master Bug#18133] LTO: TestGCCompact#test_ast_compacts segfaults on i686 — "vo.x (Vit Ondruch)" <noreply@...>

Issue #18133 has been reported by vo.x (Vit Ondruch).

25 messages 2021/08/25

[#105077] [Ruby master Feature#18136] take_while_after — "zverok (Victor Shepelev)" <noreply@...>

Issue #18136 has been reported by zverok (Victor Shepelev).

21 messages 2021/08/27

[ruby-core:105090] [Ruby master Feature#17287] Faster Pathname FileUtils methods

From: "hsbt (Hiroshi SHIBATA)" <noreply@...>
Date: 2021-08-30 06:53:32 UTC
List: ruby-core #105090
Issue #17287 has been updated by hsbt (Hiroshi SHIBATA).

Assignee set to hsbt (Hiroshi SHIBATA)
Status changed from Open to Closed

Merged at https://github.com/ruby/ruby/commit/51070ee5c4e83a4faa0feb72f08d1d9fef18b016

----------------------------------------
Feature #17287:  Faster Pathname FileUtils methods
https://bugs.ruby-lang.org/issues/17287#change-93499

* Author: schneems (Richard Schneeman)
* Status: Closed
* Priority: Normal
* Assignee: hsbt (Hiroshi SHIBATA)
----------------------------------------
I have a patch that I would like to merge into Pathname for increased performance. I understand that akr maintains pathname and may not be on GitHub. Here is a link to my patch:

https://github.com/ruby/ruby/pull/3693

Here is the diff:

```
$ git diff master
diff --git a/ext/pathname/lib/pathname.rb b/ext/pathname/lib/pathname.rb
index e6fb90277d..c3af24837f 100644
--- a/ext/pathname/lib/pathname.rb
+++ b/ext/pathname/lib/pathname.rb
@@ -575,12 +575,13 @@ def find(ignore_error: true) # :yield: pathname


 class Pathname    # * FileUtils *
+  autoload(:FileUtils, 'fileutils')
+
   # Creates a full path, including any intermediate directories that don't yet
   # exist.
   #
   # See FileUtils.mkpath and FileUtils.mkdir_p
   def mkpath
-    require 'fileutils'
     FileUtils.mkpath(@path)
     nil
   end
@@ -591,7 +592,6 @@ def mkpath
   def rmtree
     # The name "rmtree" is borrowed from File::Path of Perl.
     # File::Path provides "mkpath" and "rmtree".
-    require 'fileutils'
     FileUtils.rm_r(@path)
     nil
   end
```

## Description

Currently when calling any of the "FileUtils" methods on pathname `require` is called every time even though that library might already be loaded. This is slow.

We can speed it up by either checking first if the constant is already defined, or by using autoload.

Using defined speeds up the action by about 300x and using autoload is about twice as fast as that (600x faster than current require method).

I'm proposing we use autoload:

```ruby
require 'benchmark/ips'

Benchmark.ips do |x|
  autoload(:FileUtils, "fileutils")
  x.report("require") { require 'fileutils' }
  x.report("defined") { require 'fileutils' unless defined?(FileUtils) }
  x.report("autoload") { FileUtils }

  x.compare!
end

# Warming up --------------------------------------
#              require     3.624k i/100ms
#              defined     1.465M i/100ms
#             autoload     2.320M i/100ms
# Calculating -------------------------------------
#              require     36.282k (2.4%) i/s -    184.824k in   5.097153s
#              defined     14.539M (ア 2.0%) i/s -     73.260M in   5.041161s
#             autoload     23.100M (ア 1.9%) i/s -    115.993M in   5.023271s

# Comparison:
#             autoload: 23099779.2 i/s
#              defined: 14538544.9 i/s - 1.59x  (ア 0.00) slower
#              require:    36282.3 i/s - 636.67x  (ア 0.00) slower
```

Because this autoload is scoped to Pathname it will not change the behavior of existing programs that are not expecting FileUtils to be loaded yet:

```
ruby -rpathname -e "class Pathname; autoload(:FileUtils, 'fileutils'); end; puts FileUtils.exist?('foo')"
Traceback (most recent call last):
-e:1:in `<main>': uninitialized constant FileUtils (NameError)
```





-- 
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>

In This Thread

Prev Next