ruby-changes:62875
From: Jean <ko1@a...>
Date: Thu, 10 Sep 2020 03:11:56 +0900 (JST)
Subject: [ruby-changes:62875] 5001cc4716 (master): Optimize ObjectSpace.dump_all
https://git.ruby-lang.org/ruby.git/commit/?id=5001cc4716 From 5001cc47169614ea07d87651c95c2ee185e374e0 Mon Sep 17 00:00:00 2001 From: Jean Boussier <jean.boussier@g...> Date: Tue, 18 Aug 2020 09:41:38 +0200 Subject: Optimize ObjectSpace.dump_all The two main optimization are: - buffer writes for improved performance - avoid formatting functions when possible ``` | |compare-ruby|built-ruby| |:------------------|-----------:|---------:| |dump_all_string | 1.038| 195.925| | | -| 188.77x| |dump_all_file | 33.453| 139.645| | | -| 4.17x| |dump_all_dev_null | 44.030| 278.552| | | -| 6.33x| ``` diff --git a/benchmark/objspace_dump_all.yml b/benchmark/objspace_dump_all.yml new file mode 100644 index 0000000..ebab562 --- /dev/null +++ b/benchmark/objspace_dump_all.yml @@ -0,0 +1,13 @@ https://github.com/ruby/ruby/blob/trunk/benchmark/objspace_dump_all.yml#L1 +prelude: | + require 'objspace' + require 'tempfile' + $objs = 1_000.times.map { Object.new } + $strings = 1_000.times.map { |i| "string #{i}" } + $file = Tempfile.new('heap') + $dev_null = File.open(File::NULL, 'w+') + +benchmark: + dump_all_string: "ObjectSpace.dump_all(output: :string)" + dump_all_file: "ObjectSpace.dump_all(output: $file)" + dump_all_dev_null: "ObjectSpace.dump_all(output: $dev_null)" +loop_count: 1 diff --git a/ext/objspace/depend b/ext/objspace/depend index 1a5d0db..1dc10c4 100644 --- a/ext/objspace/depend +++ b/ext/objspace/depend @@ -2,6 +2,22 @@ https://github.com/ruby/ruby/blob/trunk/ext/objspace/depend#L2 object_tracing.o: $(RUBY_EXTCONF_H) object_tracing.o: $(arch_hdrdir)/ruby/config.h object_tracing.o: $(hdrdir)/ruby.h +object_tracing.o: $(hdrdir)/ruby/assert.h +object_tracing.o: $(hdrdir)/ruby/backward.h +object_tracing.o: $(hdrdir)/ruby/backward/2/assume.h +object_tracing.o: $(hdrdir)/ruby/backward/2/attributes.h +object_tracing.o: $(hdrdir)/ruby/backward/2/bool.h +object_tracing.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h +object_tracing.o: $(hdrdir)/ruby/backward/2/inttypes.h +object_tracing.o: $(hdrdir)/ruby/backward/2/limits.h +object_tracing.o: $(hdrdir)/ruby/backward/2/long_long.h +object_tracing.o: $(hdrdir)/ruby/backward/2/r_cast.h +object_tracing.o: $(hdrdir)/ruby/backward/2/rmodule.h +object_tracing.o: $(hdrdir)/ruby/backward/2/stdalign.h +object_tracing.o: $(hdrdir)/ruby/backward/2/stdarg.h +object_tracing.o: $(hdrdir)/ruby/debug.h +object_tracing.o: $(hdrdir)/ruby/defines.h +object_tracing.o: $(hdrdir)/ruby/intern.h object_tracing.o: $(hdrdir)/ruby/internal/anyargs.h object_tracing.o: $(hdrdir)/ruby/internal/arithmetic.h object_tracing.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -142,20 +158,6 @@ object_tracing.o: $(hdrdir)/ruby/internal/value_type.h https://github.com/ruby/ruby/blob/trunk/ext/objspace/depend#L158 object_tracing.o: $(hdrdir)/ruby/internal/variable.h object_tracing.o: $(hdrdir)/ruby/internal/warning_push.h object_tracing.o: $(hdrdir)/ruby/internal/xmalloc.h -object_tracing.o: $(hdrdir)/ruby/assert.h -object_tracing.o: $(hdrdir)/ruby/backward.h -object_tracing.o: $(hdrdir)/ruby/backward/2/assume.h -object_tracing.o: $(hdrdir)/ruby/backward/2/attributes.h -object_tracing.o: $(hdrdir)/ruby/backward/2/bool.h -object_tracing.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -object_tracing.o: $(hdrdir)/ruby/backward/2/inttypes.h -object_tracing.o: $(hdrdir)/ruby/backward/2/limits.h -object_tracing.o: $(hdrdir)/ruby/backward/2/long_long.h -object_tracing.o: $(hdrdir)/ruby/backward/2/stdalign.h -object_tracing.o: $(hdrdir)/ruby/backward/2/stdarg.h -object_tracing.o: $(hdrdir)/ruby/debug.h -object_tracing.o: $(hdrdir)/ruby/defines.h -object_tracing.o: $(hdrdir)/ruby/intern.h object_tracing.o: $(hdrdir)/ruby/missing.h object_tracing.o: $(hdrdir)/ruby/ruby.h object_tracing.o: $(hdrdir)/ruby/st.h @@ -166,6 +168,22 @@ object_tracing.o: objspace.h https://github.com/ruby/ruby/blob/trunk/ext/objspace/depend#L168 objspace.o: $(RUBY_EXTCONF_H) objspace.o: $(arch_hdrdir)/ruby/config.h objspace.o: $(hdrdir)/ruby.h +objspace.o: $(hdrdir)/ruby/assert.h +objspace.o: $(hdrdir)/ruby/backward.h +objspace.o: $(hdrdir)/ruby/backward/2/assume.h +objspace.o: $(hdrdir)/ruby/backward/2/attributes.h +objspace.o: $(hdrdir)/ruby/backward/2/bool.h +objspace.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h +objspace.o: $(hdrdir)/ruby/backward/2/inttypes.h +objspace.o: $(hdrdir)/ruby/backward/2/limits.h +objspace.o: $(hdrdir)/ruby/backward/2/long_long.h +objspace.o: $(hdrdir)/ruby/backward/2/r_cast.h +objspace.o: $(hdrdir)/ruby/backward/2/rmodule.h +objspace.o: $(hdrdir)/ruby/backward/2/stdalign.h +objspace.o: $(hdrdir)/ruby/backward/2/stdarg.h +objspace.o: $(hdrdir)/ruby/defines.h +objspace.o: $(hdrdir)/ruby/encoding.h +objspace.o: $(hdrdir)/ruby/intern.h objspace.o: $(hdrdir)/ruby/internal/anyargs.h objspace.o: $(hdrdir)/ruby/internal/arithmetic.h objspace.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -307,20 +325,6 @@ objspace.o: $(hdrdir)/ruby/internal/value_type.h https://github.com/ruby/ruby/blob/trunk/ext/objspace/depend#L325 objspace.o: $(hdrdir)/ruby/internal/variable.h objspace.o: $(hdrdir)/ruby/internal/warning_push.h objspace.o: $(hdrdir)/ruby/internal/xmalloc.h -objspace.o: $(hdrdir)/ruby/assert.h -objspace.o: $(hdrdir)/ruby/backward.h -objspace.o: $(hdrdir)/ruby/backward/2/assume.h -objspace.o: $(hdrdir)/ruby/backward/2/attributes.h -objspace.o: $(hdrdir)/ruby/backward/2/bool.h -objspace.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -objspace.o: $(hdrdir)/ruby/backward/2/inttypes.h -objspace.o: $(hdrdir)/ruby/backward/2/limits.h -objspace.o: $(hdrdir)/ruby/backward/2/long_long.h -objspace.o: $(hdrdir)/ruby/backward/2/stdalign.h -objspace.o: $(hdrdir)/ruby/backward/2/stdarg.h -objspace.o: $(hdrdir)/ruby/defines.h -objspace.o: $(hdrdir)/ruby/encoding.h -objspace.o: $(hdrdir)/ruby/intern.h objspace.o: $(hdrdir)/ruby/io.h objspace.o: $(hdrdir)/ruby/missing.h objspace.o: $(hdrdir)/ruby/onigmo.h @@ -349,6 +353,23 @@ objspace.o: {$(VPATH)}id.h https://github.com/ruby/ruby/blob/trunk/ext/objspace/depend#L353 objspace_dump.o: $(RUBY_EXTCONF_H) objspace_dump.o: $(arch_hdrdir)/ruby/config.h objspace_dump.o: $(hdrdir)/ruby.h +objspace_dump.o: $(hdrdir)/ruby/assert.h +objspace_dump.o: $(hdrdir)/ruby/backward.h +objspace_dump.o: $(hdrdir)/ruby/backward/2/assume.h +objspace_dump.o: $(hdrdir)/ruby/backward/2/attributes.h +objspace_dump.o: $(hdrdir)/ruby/backward/2/bool.h +objspace_dump.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h +objspace_dump.o: $(hdrdir)/ruby/backward/2/inttypes.h +objspace_dump.o: $(hdrdir)/ruby/backward/2/limits.h +objspace_dump.o: $(hdrdir)/ruby/backward/2/long_long.h +objspace_dump.o: $(hdrdir)/ruby/backward/2/r_cast.h +objspace_dump.o: $(hdrdir)/ruby/backward/2/rmodule.h +objspace_dump.o: $(hdrdir)/ruby/backward/2/stdalign.h +objspace_dump.o: $(hdrdir)/ruby/backward/2/stdarg.h +objspace_dump.o: $(hdrdir)/ruby/debug.h +objspace_dump.o: $(hdrdir)/ruby/defines.h +objspace_dump.o: $(hdrdir)/ruby/encoding.h +objspace_dump.o: $(hdrdir)/ruby/intern.h objspace_dump.o: $(hdrdir)/ruby/internal/anyargs.h objspace_dump.o: $(hdrdir)/ruby/internal/arithmetic.h objspace_dump.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -489,21 +510,6 @@ objspace_dump.o: $(hdrdir)/ruby/internal/value_type.h https://github.com/ruby/ruby/blob/trunk/ext/objspace/depend#L510 objspace_dump.o: $(hdrdir)/ruby/internal/variable.h objspace_dump.o: $(hdrdir)/ruby/internal/warning_push.h objspace_dump.o: $(hdrdir)/ruby/internal/xmalloc.h -objspace_dump.o: $(hdrdir)/ruby/assert.h -objspace_dump.o: $(hdrdir)/ruby/backward.h -objspace_dump.o: $(hdrdir)/ruby/backward/2/assume.h -objspace_dump.o: $(hdrdir)/ruby/backward/2/attributes.h -objspace_dump.o: $(hdrdir)/ruby/backward/2/bool.h -objspace_dump.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -objspace_dump.o: $(hdrdir)/ruby/backward/2/inttypes.h -objspace_dump.o: $(hdrdir)/ruby/backward/2/limits.h -objspace_dump.o: $(hdrdir)/ruby/backward/2/long_long.h -objspace_dump.o: $(hdrdir)/ruby/backward/2/stdalign.h -objspace_dump.o: $(hdrdir)/ruby/backward/2/stdarg.h -objspace_dump.o: $(hdrdir)/ruby/debug.h -objspace_dump.o: $(hdrdir)/ruby/defines.h -objspace_dump.o: $(hdrdir)/ruby/encoding.h -objspace_dump.o: $(hdrdir)/ruby/intern.h objspace_dump.o: $(hdrdir)/ruby/io.h objspace_dump.o: $(hdrdir)/ruby/missing.h objspace_dump.o: $(hdrdir)/ruby/onigmo.h @@ -512,6 +518,7 @@ objspace_dump.o: $(hdrdir)/ruby/ruby.h https://github.com/ruby/ruby/blob/trunk/ext/objspace/depend#L518 objspace_dump.o: $(hdrdir)/ruby/st.h objspace_dump.o: $(hdrdir)/ruby/subst.h objspace_dump.o: $(hdrdir)/ruby/thread_native.h +objspace_dump.o: $(hdrdir)/ruby/util.h objspace_dump.o: $(top_srcdir)/ccan/check_type/check_type.h objspace_dump.o: $(top_srcdir)/ccan/container_of/container_of.h objspace_dump.o: $(top_srcdir)/ccan/list/list.h diff --git a/ext/objspace/objspace_dump.c b/ext/objspace/objspace_dump.c index f4fb33e..35a7282 100644 --- a/ext/objspace/objspace_dump.c +++ b/ext/objspace/objspace_dump.c @@ -19,15 +19,20 @@ https://github.com/ruby/ruby/blob/trunk/ext/objspace/objspace_dump.c#L19 #include "node.h" #include "objspace.h" #include "ruby/debug.h" +#include "ruby/util.h" #include "ruby/io.h" #include "vm_core.h" +RUBY_EXTERN const char ruby_hexdigits[]; + static VALUE sym_output, sym_stdout, sym_string, sym_file; static VALUE sym_full, sym_since; +#define BUFFER_CAPACITY 4096 + struct dump_config { VALUE type; - FILE *stream; + VALUE stream; VALUE string; const char *root_category; VALUE cur_obj; @@ -37,22 +42,141 @@ struct dump_config { https://github.com/ruby/ruby/blob/trunk/ext/objspace/objspace_dump.c#L42 unsigned int full_heap: 1; unsigned int partial_dump; size_t since; + unsigned long buffer_len; + char buffer[BUFFER_CAPACITY]; }; -PRINTF_ARGS(static void dump_append(struct dump_config *, const char *, .. (... truncated) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/