* Enhanced RDoc for Array#fill
* Update array.c
There's one more at 5072. I'll get it.
Co-authored-by: Eric Hodel <drbrain@segment7.net>
* Update array.c
Co-authored-by: Eric Hodel <drbrain@segment7.net>
* Update array.c
Co-authored-by: Eric Hodel <drbrain@segment7.net>
* Update array.c
Co-authored-by: Eric Hodel <drbrain@segment7.net>
* Update array.c
Co-authored-by: Eric Hodel <drbrain@segment7.net>
* Update array.c
Co-authored-by: Eric Hodel <drbrain@segment7.net>
For the most common cases of `rotate!` one place to the right or to the
left, instead of doing some reversals of the array we just keep a single
value in a temporary value, use memmove and then put the temporary
value where it should be.
Saves comitters' daily life by avoid #include-ing everything from
internal.h to make each file do so instead. This would significantly
speed up incremental builds.
We take the following inclusion order in this changeset:
1. "ruby/config.h", where _GNU_SOURCE is defined (must be the very
first thing among everything).
2. RUBY_EXTCONF_H if any.
3. Standard C headers, sorted alphabetically.
4. Other system headers, maybe guarded by #ifdef
5. Everything else, sorted alphabetically.
Exceptions are those win32-related headers, which tend not be self-
containing (headers have inclusion order dependencies).
These functions are used from within a compilation unit so we can
make them static, for better binary size. This changeset reduces
the size of generated ruby binary from 26,590,128 bytes to
26,584,472 bytes on my macihne.
This removes the related tests, and puts the related specs behind
version guards. This affects all code in lib, including some
libraries that may want to support older versions of Ruby.
The declaration of local variable in loop, it will initialize local variable for each run of the loop with clang generated code.
So, it shouldn't declare the local variable in heavy loop.
Array#sum with float elements will be faster around 30%.
* Before
user system total real
3.320000 0.010000 3.330000 ( 3.336088)
* After
user system total real
2.590000 0.010000 2.600000 ( 2.602399)
* Test code
require 'benchmark'
Benchmark.bmbm do |x|
ary = []
10000.times { ary << Random.rand }
x.report do
50000.times do
ary.sum
end
end
end
to suppress the following warning:
```
compiling cxxanyargs.cpp
In file included from cxxanyargs.cpp:1:
In file included from ../../.././include/ruby/ruby.h:2150:
../../.././include/ruby/intern.h:56:19: warning: 'register' storage class specifier is deprecated and incompatible with C++17 [-Wdeprecated-register]
void rb_mem_clear(register VALUE*, register long);
^~~~~~~~~
../../.././include/ruby/intern.h:56:36: warning: 'register' storage class specifier is deprecated and incompatible with C++17 [-Wdeprecated-register]
void rb_mem_clear(register VALUE*, register long);
^~~~~~~~~
```
Previously, Array#uniq would return subclass instance if the
length of the array were 2 or greater, and would return Array
instance if the length of the array were 0 or 1.
Fixes [Bug #7768]
My previous attempt to correct #2068 apparently failed and the confusing
wording ("instances") was merged into trunk instead.
This should address any potential confusion.
rb_str_buf_new always allocates at least 127 bytes of capacity, even
when less is requested.
> ObjectSpace.dump(%w[a b c].join)
{"address":"0x7f935f06ebf0", "type":"STRING", "class":"0x7f935d8b7bb0", "bytesize":3, "capacity":127, "value":"abc", "encoding":"UTF-8", "memsize":168, "flags":{"wb_protected":true}}
Instead, by using rb_str_new and then setting the length to 0, we can
allocate the exact amount of memory needed, without extra capacity.
> ObjectSpace.dump(%w[a b c].join)
{"address":"0x7f903fcab530", "type":"STRING", "class":"0x7f903f8b7988", "embedded":true, "bytesize":3, "value":"abc", "encoding":"UTF-8", "memsize":40, "flags":{"wb_protected":true}}
ARY_SHARED_P and ARY_EMBED_P included:
assert(!FL_TEST((ary), ELTS_SHARED) || !FL_TEST((ary), RARRAY_EMBED_FLAG)),
The two predicate macros are used in many other assert conditions,
which caused memory bloat during C compilation.
This change factors out the assertion above to a function.
Now gcc consumes 160 MB instead of 250 MB to compile array.c.
The assertion blows up gcc 8 by consuming approx. 1.8 GB memory.
This change reduces the amount of memory required to about 200 MB.
A follow-up of ae750799c1.
Shared arrays created by Array#dup and so on points
a shared_root object to manage lifetime of Array buffer.
However, sometimes shared_root is called only shared so
it is confusing. So I fixed these wording "shared" to "shared_root".
* RArray::heap::aux::shared -> RArray::heap::aux::shared_root
* ARY_SHARED() -> ARY_SHARED_ROOT()
* ARY_SHARED_NUM() -> ARY_SHARED_ROOT_REFCNT()
Also, add some debug_counters to count shared array objects.
* ary_shared_create: shared ary by Array#dup and so on.
* ary_shared: finished in shard.
* ary_shared_root_occupied: shared_root but has only 1 refcnt.
The number (ary_shared - ary_shared_root_occupied) is meaningful.
Array#minmax was previous not implemented, so calling #minmax on
array was actually calling Enumerable#minmax. This is a simple
implementation of #minmax by just calling rb_ary_min and
rb_ary_max, which improves performance significantly.
Fixes [Bug #15929]
For array.c (Array#sort) and enum.c (Enumerable#sort_by),
add comments mentioning that sort.reverse! / sort_by { ... }.reverse!
can/should be used to reverse the result. [ci skip]
* array.c (rb_ary_join_m): warn use of non-nil $,.
* io.c (rb_output_fs_setter): warn when set to non-nil value.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67606 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Because hard to specify commits related to r67479 only.
So please commit again.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67499 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Currently we are not explicit enough regarding the potentially confusing
behavior of `Array#-` and `Array#difference` when it comes to duplicate items
within receiver arrays.
Although the original documentation for these methods does use an array with
multiple instance of the same integers, the explanation for the behavior is
actually imprecise.
> removing any items that also appear in +other_ary+
Not only does `Array#-` remove any items that also appear in `other_ary` but
it also remove any instance of any item in `other_ary`.
One may expect `Array#-` to behave like mathematical subtraction or difference
when it doesn't. One could be forgiven to expect the following behavior:
```ruby
[1,1,2,2,3,3,4,4] - [1,2,3,4]
=> [1,2,3,4]
```
In reality this is the result:
```ruby
[1,1,2,2,3,3,4,4] - [1,2,3,4]
=> []
```
I hope that I've prevented this potential confusion with the clarifications
in this change. I can offer this as evidence of likeliness for confusion:
https://twitter.com/olivierlacan/status/1084930269533085696
I'll freely admit I was surprised by this behavior myself since I needed to
obtain an Array with only one instance of each item in the argument array
removed.
[Fix GH-2068] [ci skip]
From: Olivier Lacan <hi@olivierlacan.com>
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66831 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Before this patch, if `reject!` is called on a shared array it can
mutate the shared array rather than a copy. This patch marks the array
as "going to be modified" so that the shared source array isn't
mutated.
[Bug #15479] [ruby-core:90781]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66756 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* array.c (rb_ary_splice): do not use RARRAY_PTR() here because it can cause
GC because of rb_ary_detransient(). Here ary can contain T_NONE object
because of increasing capacity and not initialized yet.
error log: http://ci.rvm.jp/results/trunk-test@ruby-sky1/1557174
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66513 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* internal.h: rename the following names:
* li_table -> ar_table. "li" means linear (from linear search),
but we use the word "array" (from data layout).
* RHASH_ARRAY -> RHASH_AR_TABLE. AR_TABLE is more clear.
* rb_hash_array_* -> rb_hash_ar_table_*.
* RHASH_TABLE_P() -> RHASH_ST_TABLE_P(). more clear.
* RHASH_CLEAR() -> RHASH_ST_CLEAR().
* hash.c: rename "linear_" prefix functions to "ar_" prefix.
* hash.c (linear_init_table): rename to ar_alloc_table.
* debug_counter.h: rename obj_hash_array to obj_hash_ar.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66390 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Before this patch Array#all? was not implemented in Array class
and alternatively Enumerable#all? was used, while #any? has its
own method entry in Array class. Similarly, Array#none? and #one?
also lacks its own implementation.
This patch provides Array-specific implementations for above three
methods to enable faster method lookup.
[Fix GH-2041]
From: Koji Onishi <fursich0@gmail.com>
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66212 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* include/ruby/ruby.h: de-transient at
`RARRAY_PTR_USE` and `RARRAY_PTR_USE_START`.
Introduce `RARRAY_PTR_USE_TRANSIENT` and
`RARRAY_PTR_USE_START_TRANSIENT` if you don't want to
de-transient an array. Generally, it is difficult
so C-extension writers should not use them.
* array.c: use `RARRAY_PTR_USE_TRANSIENT` if possible.
* hash.c: ditto.
* enum.c (enum_sort_by): remove `rb_ary_transient_heap_evacuate()`
because `RARRAY_PTR_USE` do de-transient.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66165 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
In this example code:
```ruby
def foo
[1, 2, 3, 4]
end
```
The array literal uses a `duparray` instruction. Before this patch,
`rb_ary_resurrect` would malloc and memcpy a new array buffer. This
patch changes `rb_ary_resurrect` to use `ary_make_partial` so that the
new array object shares the underlying buffer with the array stored in
the instruction sequences.
Before this patch, the new array object is not shared:
```
$ ruby -r objspace -e'p ObjectSpace.dump([1, 2, 3, 4])'
"{\"address\":\"0x7fa2718372d0\", \"type\":\"ARRAY\", \"class\":\"0x7fa26f8b0010\", \"length\":4, \"memsize\":72, \"flags\":{\"wb_protected\":true}}\n"
```
After this patch:
```
$ ./ruby -r objspace -e'p ObjectSpace.dump([1, 2, 3, 4])'
"{\"address\":\"0x7f9a76883638\", \"type\":\"ARRAY\", \"class\":\"0x7f9a758af900\", \"length\":4, \"shared\":true, \"references\":[\"0x7f9a768837c8\"], \"memsize\":40, \"flags\":{\"wb_protected\":true}}\n"
```
[Feature #15289] [ruby-core:90097]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66095 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This args[1]-- overflows when it is zero. Should do that only
when we can say it is nonzero.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65798 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* hash.c, internal.h: support theap for small Hash.
Introduce RHASH_ARRAY (li_table) besides st_table and small Hash
(<=8 entries) are managed by an array data structure.
This array data can be managed by theap.
If st_table is needed, then converting array data to st_table data.
For st_table using code, we prepare "stlike" APIs which accepts hash value
and are very similar to st_ APIs.
This work is based on the GSoC achievement
by tacinight <tacingiht@gmail.com> and refined by ko1.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65454 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* transient_heap.c, transient_heap.h: implement TransientHeap (theap).
theap is designed for Ruby's object system. theap is like Eden heap
on generational GC terminology. theap allocation is very fast because
it only needs to bump up pointer and deallocation is also fast because
we don't do anything. However we need to evacuate (Copy GC terminology)
if theap memory is long-lived. Evacuation logic is needed for each type.
See [Bug #14858] for details.
* array.c: Now, theap for T_ARRAY is supported.
ary_heap_alloc() tries to allocate memory area from theap. If this trial
sccesses, this array has theap ptr and RARRAY_TRANSIENT_FLAG is turned on.
We don't need to free theap ptr.
* ruby.h: RARRAY_CONST_PTR() returns malloc'ed memory area. It menas that
if ary is allocated at theap, force evacuation to malloc'ed memory.
It makes programs slow, but very compatible with current code because
theap memory can be evacuated (theap memory will be recycled).
If you want to get transient heap ptr, use RARRAY_CONST_PTR_TRANSIENT()
instead of RARRAY_CONST_PTR(). If you can't understand when evacuation
will occur, use RARRAY_CONST_PTR().
(re-commit of r65444)
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65449 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* transient_heap.c, transient_heap.h: implement TransientHeap (theap).
theap is designed for Ruby's object system. theap is like Eden heap
on generational GC terminology. theap allocation is very fast because
it only needs to bump up pointer and deallocation is also fast because
we don't do anything. However we need to evacuate (Copy GC terminology)
if theap memory is long-lived. Evacuation logic is needed for each type.
See [Bug #14858] for details.
* array.c: Now, theap for T_ARRAY is supported.
ary_heap_alloc() tries to allocate memory area from theap. If this trial
sccesses, this array has theap ptr and RARRAY_TRANSIENT_FLAG is turned on.
We don't need to free theap ptr.
* ruby.h: RARRAY_CONST_PTR() returns malloc'ed memory area. It menas that
if ary is allocated at theap, force evacuation to malloc'ed memory.
It makes programs slow, but very compatible with current code because
theap memory can be evacuated (theap memory will be recycled).
If you want to get transient heap ptr, use RARRAY_CONST_PTR_TRANSIENT()
instead of RARRAY_CONST_PTR(). If you can't understand when evacuation
will occur, use RARRAY_CONST_PTR().
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65444 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* array.c: [DOC] small doc fixes for Array#difference and Array#-.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65184 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* array.c: [DOC] use `<code>other_ary</code>s' instead of `+other_ary+s',
which is not rendered correctly.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65066 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* array.c (yield_indexed_values): use RARRAY_AREF/ASET instead of
using RARRAY_PTR().
* enum.c (nmin_filter): ditto.
* proc.c (rb_sym_to_proc): ditto.
* enum.c (rb_nmin_run): use RARRAY_PTR_USE() instead of RARRAY_PTR().
It is safe because they don't make new referecen from an array.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64986 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
I introduce a `difference` method equivalent to the `-` operator, but
which accept more than array as argument. This improved readability, and
it is also coherent with the `+` operator, which has a similar `concat`
method. The method doesn't modify the original object and return a new
object instead. I plan to introduce a `difference!` method as well.
Tests and documentation are included.
It solves partially https://bugs.ruby-lang.org/issues/14097
From: Ana María Martínez Gómez <ammartinez@suse.de>
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64921 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Avoid repeating code and improve readability in `rb_ary_or` and
`rb_ary_union_multi`. Similaty as done with `rb_ary_union`.
[Fix GH-1747] [Feature #14097]
From: Ana María Martínez Gómez <ammartinez@suse.de>
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64790 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
`Array#uniq` is not really related with `Array#|`, so I replaced it by
`Array#union`.
[Fix GH-1747] [Feature #14097]
From: Ana María Martínez Gómez <ammartinez@suse.de>
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64789 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Avoid repeating code and improve readability in `rb_ary_or` and
`rb_ary_union_multi`.
[Fix GH-1747] [Feature #14097]
From: Ana María Martínez Gómez <ammartinez@suse.de>
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64788 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
I introduce a `union` method equivalent to the `|` operator, but which
accept more than array as argument. This improved readability, and it
is also coherent with the `+` operator, which has a similar `concat`
method. The method doesn't modify the original object and return a new
object instead. It is plan to introduce a `union!` method as well.
Tests and documentation are included.
It solves partially https://bugs.ruby-lang.org/issues/14097
[Fix GH-1747] [Feature #14097]
From: Ana María Martínez Gómez <ammartinez@suse.de>
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64787 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_args.c: rb_ary_dup(args->rest) to be used at most once during
parameter setup. [Feature #15010]
A patch by chopraanmol1 (Anmol Chopra) <chopraanmol1@gmail.com>.
* array.c (rb_ary_behead): added to remove first n elements.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64583 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Part of the plan to reduce dependencies on malloc_usable_size
which costs us speed: https://bugs.ruby-lang.org/issues/10238
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63481 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* array.c (rb_ary_collect): yield in block argument semantics
always to splat array elements to lambda, for the backward
compatibility. [ruby-core:86362] [Bug #14639]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63030 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* In Enumerable, Enumerator::Lazy, Array, Hash and Set
[Feature #13784] [ruby-core:82285]
* Share specs for the various #select#select! methods and
reuse them for #filter/#filter!.
* Add corresponding filter tests for select tests.
* Update NEWS.
[Fix GH-1824]
From: Alexander Patrick <adp90@case.edu>
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62575 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* array.c (rb_ary_sample): Adds examples for the use of the
optional parameter random for Array#sample and unifies the style
with the documentation of Array#shuffle.
[Fix GH-1825]
From: Alberto Almagro <alberto.almagro@rakuten.com>
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62553 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* array.c (rb_ary_values_at): optimization range argument case.
bulk concatenation than pushing for each element.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62413 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
which has been developed by Takashi Kokubun <takashikkbn@gmail> as
YARV-MJIT. Many of its bugs are fixed by wanabe <s.wanabe@gmail.com>.
This JIT compiler is designed to be a safe migration path to introduce
JIT compiler to MRI. So this commit does not include any bytecode
changes or dynamic instruction modifications, which are done in original
MJIT.
This commit even strips off some aggressive optimizations from
YARV-MJIT, and thus it's slower than YARV-MJIT too. But it's still
fairly faster than Ruby 2.5 in some benchmarks (attached below).
Note that this JIT compiler passes `make test`, `make test-all`, `make
test-spec` without JIT, and even with JIT. Not only it's perfectly safe
with JIT disabled because it does not replace VM instructions unlike
MJIT, but also with JIT enabled it stably runs Ruby applications
including Rails applications.
I'm expecting this version as just "initial" JIT compiler. I have many
optimization ideas which are skipped for initial merging, and you may
easily replace this JIT compiler with a faster one by just replacing
mjit_compile.c. `mjit_compile` interface is designed for the purpose.
common.mk: update dependencies for mjit_compile.c.
internal.h: declare `rb_vm_insn_addr2insn` for MJIT.
vm.c: exclude some definitions if `-DMJIT_HEADER` is provided to
compiler. This avoids to include some functions which take a long time
to compile, e.g. vm_exec_core. Some of the purpose is achieved in
transform_mjit_header.rb (see `IGNORED_FUNCTIONS`) but others are
manually resolved for now. Load mjit_helper.h for MJIT header.
mjit_helper.h: New. This is a file used only by JIT-ed code. I'll
refactor `mjit_call_cfunc` later.
vm_eval.c: add some #ifdef switches to skip compiling some functions
like Init_vm_eval.
win32/mkexports.rb: export thread/ec functions, which are used by MJIT.
include/ruby/defines.h: add MJIT_FUNC_EXPORTED macro alis to clarify
that a function is exported only for MJIT.
array.c: export a function used by MJIT.
bignum.c: ditto.
class.c: ditto.
compile.c: ditto.
error.c: ditto.
gc.c: ditto.
hash.c: ditto.
iseq.c: ditto.
numeric.c: ditto.
object.c: ditto.
proc.c: ditto.
re.c: ditto.
st.c: ditto.
string.c: ditto.
thread.c: ditto.
variable.c: ditto.
vm_backtrace.c: ditto.
vm_insnhelper.c: ditto.
vm_method.c: ditto.
I would like to improve maintainability of function exports, but I
believe this way is acceptable as initial merging if we clarify the
new exports are for MJIT (so that we can use them as TODO list to fix)
and add unit tests to detect unresolved symbols.
I'll add unit tests of JIT compilations in succeeding commits.
Author: Takashi Kokubun <takashikkbn@gmail.com>
Contributor: wanabe <s.wanabe@gmail.com>
Part of [Feature #14235]
---
* Known issues
* Code generated by gcc is faster than clang. The benchmark may be worse
in macOS. Following benchmark result is provided by gcc w/ Linux.
* Performance is decreased when Google Chrome is running
* JIT can work on MinGW, but it doesn't improve performance at least
in short running benchmark.
* Currently it doesn't perform well with Rails. We'll try to fix this
before release.
---
* Benchmark reslts
Benchmarked with:
Intel 4.0GHz i7-4790K with 16GB memory under x86-64 Ubuntu 8 Cores
- 2.0.0-p0: Ruby 2.0.0-p0
- r62186: Ruby trunk (early 2.6.0), before MJIT changes
- JIT off: On this commit, but without `--jit` option
- JIT on: On this commit, and with `--jit` option
** Optcarrot fps
Benchmark: https://github.com/mame/optcarrot
| |2.0.0-p0 |r62186 |JIT off |JIT on |
|:--------|:--------|:--------|:--------|:--------|
|fps |37.32 |51.46 |51.31 |58.88 |
|vs 2.0.0 |1.00x |1.38x |1.37x |1.58x |
** MJIT benchmarks
Benchmark: https://github.com/benchmark-driver/mjit-benchmarks
(Original: https://github.com/vnmakarov/ruby/tree/rtl_mjit_branch/MJIT-benchmarks)
| |2.0.0-p0 |r62186 |JIT off |JIT on |
|:----------|:--------|:--------|:--------|:--------|
|aread |1.00 |1.09 |1.07 |2.19 |
|aref |1.00 |1.13 |1.11 |2.22 |
|aset |1.00 |1.50 |1.45 |2.64 |
|awrite |1.00 |1.17 |1.13 |2.20 |
|call |1.00 |1.29 |1.26 |2.02 |
|const2 |1.00 |1.10 |1.10 |2.19 |
|const |1.00 |1.11 |1.10 |2.19 |
|fannk |1.00 |1.04 |1.02 |1.00 |
|fib |1.00 |1.32 |1.31 |1.84 |
|ivread |1.00 |1.13 |1.12 |2.43 |
|ivwrite |1.00 |1.23 |1.21 |2.40 |
|mandelbrot |1.00 |1.13 |1.16 |1.28 |
|meteor |1.00 |2.97 |2.92 |3.17 |
|nbody |1.00 |1.17 |1.15 |1.49 |
|nest-ntimes|1.00 |1.22 |1.20 |1.39 |
|nest-while |1.00 |1.10 |1.10 |1.37 |
|norm |1.00 |1.18 |1.16 |1.24 |
|nsvb |1.00 |1.16 |1.16 |1.17 |
|red-black |1.00 |1.02 |0.99 |1.12 |
|sieve |1.00 |1.30 |1.28 |1.62 |
|trees |1.00 |1.14 |1.13 |1.19 |
|while |1.00 |1.12 |1.11 |2.41 |
** Discourse's script/bench.rb
Benchmark: https://github.com/discourse/discourse/blob/v1.8.7/script/bench.rb
NOTE: Rails performance was somehow a little degraded with JIT for now.
We should fix this.
(At least I know opt_aref is performing badly in JIT and I have an idea
to fix it. Please wait for the fix.)
*** JIT off
Your Results: (note for timings- percentile is first, duration is second in millisecs)
categories_admin:
50: 17
75: 18
90: 22
99: 29
home_admin:
50: 21
75: 21
90: 27
99: 40
topic_admin:
50: 17
75: 18
90: 22
99: 32
categories:
50: 35
75: 41
90: 43
99: 77
home:
50: 39
75: 46
90: 49
99: 95
topic:
50: 46
75: 52
90: 56
99: 101
*** JIT on
Your Results: (note for timings- percentile is first, duration is second in millisecs)
categories_admin:
50: 19
75: 21
90: 25
99: 33
home_admin:
50: 24
75: 26
90: 30
99: 35
topic_admin:
50: 19
75: 20
90: 25
99: 30
categories:
50: 40
75: 44
90: 48
99: 76
home:
50: 42
75: 48
90: 51
99: 89
topic:
50: 49
75: 55
90: 58
99: 99
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62197 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This is redundant since r15206 /
ffe425ecaa as we no longer lock
the array during sort. Instead, fall back to Object#frozen?
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62154 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* array.c (rb_check_to_array): conversion to array by to_a method.
returns nil if not possible.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62072 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
r61827, r61947 was about to fix this. The proper way to allocate
memory region is called ALLOCV_N.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61949 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
r61827 was about to fix this. The proper way to allocate memory
region is called ALLOCV_N.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61947 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
It seems HUGE_VAL is already used. Why not eliminate INTINITY.
NAN is also float. That of double is called nan(). This is also
fixed.
Signed-off-by: Urabe, Shyouhei <shyouhei@ruby-lang.org>
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61938 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Confusion of argument order ignores this st_free_table.
Results in garbaged table not GCed.
Easily noticable when you read the compiper warnings.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61561 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
When doing the difference of a small array with a big one it is not
efficient in both time and memory to convert the second one to a hash.
From: Ana María Martínez Gómez <ammartinez@suse.de>
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61330 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
and specialized Array#any? and Hash#any?
Based on patch by D.E. Akers [#11286]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61098 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* array.c (rb_to_array_type): make public to share common code
internally.
* hash.c (rb_to_hash_type): make public to share common code
internally.
* symbol.c (rb_to_symbol_type): make public to share common code
internally.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60438 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_insnhelper.c (vm_opt_aref): optimize on other than fixnum
argument too.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60333 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
[Feature #13884]
Reduce number of memory allocations for "and", "or" and "diff"
operations on small arrays
Very often, arrays are used to filter parameters and to select
interesting items from 2 collections and very often these
collections are small enough, for example:
```ruby
SAFE_COLUMNS = [:id, :title, :created_at]
def columns
@all_columns & SAFE_COLUMNS
end
```
In this patch, I got rid of unnecessary memory allocations for
small arrays when "and", "or" and "diff" operations are performed.
name | HEAD | PATCH
-----------------+------:+------:
array_small_and | 0.615 | 0.263
array_small_diff | 0.676 | 0.282
array_small_or | 0.953 | 0.463
name | PATCH
-----------------+------:
array_small_and | 2.343
array_small_diff | 2.392
array_small_or | 2.056
name | HEAD | PATCH
-----------------+------:+------:
array_small_and | 1.429 | 1.005
array_small_diff | 1.493 | 0.878
array_small_or | 1.672 | 1.152
name | PATCH
-----------------+------:
array_small_and | 1.422
array_small_diff | 1.700
array_small_or | 1.452
Author: Dmitry Bochkarev <dimabochkarev@gmail.com>
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60057 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* array.c (binomial_coefficient): get rid of bignums by division
after each multiplications.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59692 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* array.c (rb_ary_cycle_size, descending_factorial): use
rb_int_mul instead of rb_funcallv.
* array.c (binomial_coefficient): use rb_int_idiv instead of
rb_funcallv.
* array.c (rb_ary_repeated_permutation_size): use
rb_int_positive_pow.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59689 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* array.c (ary_join_1): ignore encodings in nested arrays as an
initial encoding.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59685 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* array.c (ary_join_1): copy the encoding of the converted string
of the first element by to_str too, as an initial encoding.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59684 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This patch is sent from @selmertsx (morioka shuhei).
[fix GH-1646]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59070 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* array.c: [DOC] make example in the docs for Array#{sort,sort!}
match the call-seq and description by using the same block vars.
Based on a patch by Roque Pinel (repinel). [Fix GH-1628]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59011 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
To convert the object implicitly, it has had two parts in convert_type() which are
1. lookink up the method's id
2. calling the method
Seems that strncmp() and strcmp() in convert_type() are slightly heavy to look up
the method's id for type conversion.
This patch will add and use internal APIs (rb_convert_type_with_id, rb_check_convert_type_with_id)
to call the method without looking up the method's id when convert the object.
Array#flatten -> 19 % up
Array#+ -> 3 % up
[ruby-dev:50024] [Bug #13341] [Fix GH-1537]
### Before
Array#flatten 104.119k (± 1.1%) i/s - 525.690k in 5.049517s
Array#+ 1.993M (± 1.8%) i/s - 10.010M in 5.024258s
### After
Array#flatten 124.005k (± 1.0%) i/s - 624.240k in 5.034477s
Array#+ 2.058M (± 4.8%) i/s - 10.302M in 5.019328s
### Test Code
require 'benchmark/ips'
class Foo
def to_ary
[1,2,3]
end
end
Benchmark.ips do |x|
ary = []
100.times { |i| ary << i }
array = [ary]
x.report "Array#flatten" do |i|
i.times { array.flatten }
end
x.report "Array#+" do |i|
obj = Foo.new
i.times { array + obj }
end
end
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58978 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* array.c (rb_ary_concat_multi): concatenate the array without generating
temporary Array object if only one argument is given.
This is very similar with r58886.
Array#concat will be faster around 19%.
[Fix GH-1634]
### Before
Array#concat 2.187M (± 3.5%) i/s - 10.926M in 5.002829s
### After
Array#concat 2.598M (± 1.8%) i/s - 13.008M in 5.008201s
### Test code
require 'benchmark/ips'
Benchmark.ips do |x|
x.report "Array#concat" do |i|
other = [4]
i.times { [1, 2, 3].concat(other) }
end
end
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58909 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* object.c (rb_equal): add optimized path to compare the objects using
rb_equal_opt(). Previously, if not same objects were given, rb_equal() would
call `==' method via rb_funcall() which took a long time.
rb_equal_opt() has provided faster comparing for Fixnum/Float/String objects.
Now, Time#eql? uses rb_equal() to compare with argument object and it will
be faster around 40% on 64-bit environment.
* array.c (rb_ary_index): remove redundant rb_equal_opt() calling.
Now, rb_equal() was optimized using rb_equal_opt().
If rb_equal_opt() returns Qundef, it will invoke rb_equal() -> rb_equal_opt(),
and it will cause the performance regression.
So, this patch will remove first redundant rb_equal_opt() calling.
* array.c (rb_ary_rindex): ditto.
* array.c (rb_ary_includes): ditto.
[ruby-core:80360] [Bug #13365] [Fix GH-#1552]
### Before
Time#eql? with other 7.309M (± 1.4%) i/s - 36.647M in 5.014964s
Array#index(val) 1.433M (± 1.2%) i/s - 7.207M in 5.030942s
Array#rindex(val) 1.418M (± 1.6%) i/s - 7.103M in 5.009164s
Array#include?(val) 1.451M (± 0.9%) i/s - 7.295M in 5.026392s
### After
Time#eql? with other 10.321M (± 1.9%) i/s - 51.684M in 5.009203s
Array#index(val) 1.474M (± 0.9%) i/s - 7.433M in 5.044384s
Array#rindex(val) 1.449M (± 1.7%) i/s - 7.292M in 5.034436s
Array#include?(val) 1.466M (± 1.7%) i/s - 7.373M in 5.030047s
### Test code
require 'benchmark/ips'
Benchmark.ips do |x|
t1 = Time.now
t2 = Time.now
x.report "Time#eql? with other" do |i|
i.times { t1.eql?(t2) }
end
# Benchmarks to check whether it didn't introduce the regression
obj = Object.new
x.report "Array#index(val)" do |i|
ary = [1, 2, true, false, obj]
i.times { ary.index(obj) }
end
x.report "Array#rindex(val)" do |i|
ary = [1, 2, true, false, obj].reverse
i.times { ary.rindex(obj) }
end
x.report "Array#include?(val)" do |i|
ary = [1, 2, true, false, obj]
i.times { ary.include?(obj) }
end
end
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58880 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* array.c (ary_ensure_room_for_push): use rb_ary_modify_check() instead of
rb_ary_modify() to check whether the object can be modified for non shared
Array object. rb_ary_modify() has the codes for shared Array object too.
In here, it has condition branch for shared / non shared Array object and
it can use rb_ary_modify_check() which is smaller function than
rb_ary_modify() for non shared object.
rb_ary_modify_check() will be expand as inline function.
If it will compile with GCC, Array#<< will be faster around 8%.
[ruby-core:81082] [Bug #13553] [Fix GH-1609]
## Clang 802.0.42
### Before
Array#<< 9.353M (± 1.7%) i/s - 46.787M in 5.004123s
Array#push 7.702M (± 1.1%) i/s - 38.577M in 5.009338s
Array#values_at 6.133M (± 1.9%) i/s - 30.699M in 5.007772s
### After
Array#<< 9.458M (± 2.0%) i/s - 47.357M in 5.009069s
Array#push 7.921M (± 1.8%) i/s - 39.665M in 5.009151s
Array#values_at 6.377M (± 2.3%) i/s - 31.881M in 5.001888s
### Result
Array#<< -> 1.2% faster
Array#push -> 2.8% faster
Array#values_at -> 3.9% faster
## GCC 7.1.0
### Before
Array#<< 10.497M (± 1.1%) i/s - 52.665M in 5.017601s
Array#push 8.527M (± 1.6%) i/s - 42.777M in 5.018003s
Array#values_at 7.621M (± 1.7%) i/s - 38.152M in 5.007910s
### After
Array#<< 11.403M (± 1.3%) i/s - 57.028M in 5.001849s
Array#push 8.924M (± 1.3%) i/s - 44.609M in 4.999940s
Array#values_at 8.291M (± 1.4%) i/s - 41.487M in 5.004727s
### Result
Array#<< -> 8.3% faster
Array#push -> 4.3% faster
Array#values_at -> 8.7% faster
## Test code
require 'benchmark/ips'
Benchmark.ips do |x|
x.report "Array#<<" do |i|
i.times { [1,2] << 3 }
end
x.report "Array#push" do |i|
i.times { [1,2].push(3) }
end
x.report "Array#values_at" do |i|
ary = [1, 2, 3, 4, 5]
i.times { ary.values_at(0, 2, 4) }
end
end
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58867 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* debug_counter.h: add the following counters to measure object types.
obj_free: freed count
obj_str_ptr: freed count of Strings they have extra buff.
obj_str_embed: freed count of Strings they don't have extra buff.
obj_str_shared: freed count of Strings they have shared extra buff.
obj_str_nofree: freed count of Strings they are marked as nofree.
obj_str_fstr: freed count of Strings they are marked as fstr.
obj_ary_ptr: freed count of Arrays they have extra buff.
obj_ary_embed: freed count of Arrays they don't have extra buff.
obj_obj_ptr: freed count of Objects (T_OBJECT) they have extra buff.
obj_obj_embed: freed count of Objects they don't have extra buff.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58865 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* array.c (rb_ary_insert): fix the position in error message, when
it is less than -1.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58694 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* array.c (rb_ary_insert): check position to insert even if no
elements to be inserted. [ruby-core:81125] [Bug #13558]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58693 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Found a part where copy&paste can be eliminated. Reduces vm_exec_core
from 26,228 bytes to 26,176 bytes in size on my machine. I believe it
does not affect any runtime performance.
----
* array.c (rb_ary_tmp_new_from_values): extend existing
rb_ary_new_from_values function so that it can take
additional value for klass.
* array.c (rb_ary_new_from_values): use the new function.
* insns.def (toregexp): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58416 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
For a shared array root, struct RArray::as.heap.aux.capa stores the
number of Arrays holding reference to that T_ARRAY instead of the actual
heap-allocated capacity. Use ARY_CAPA() macro which handles this
appropriately.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58332 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* array.c: [DOC] add example for Array.new with block and index.
Reported by Don Cruickshank. [ruby-core:68442] [Bug #10944]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58037 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* array.c: [DOC] fix grammar in Array#sort, #sort!, #sort_by!,
move references below the code example, add a missing reference.
* enum.c: [DOC] fix grammar in Enumerable#sort, #sort_by.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57771 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* array.c (finish_exact_sum): add 0 and the initial value to check
if the latter is numeric. [ruby-core:79572] [Bug #13222]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57651 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Hidden objects (RBASIC_CLASS(hash) == 0) can never become
visible to other threads or signal handlers via
ObjectSpace.each_object or similar means. Thus it is safe to
forcibly recycle the object slot for future use, here.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57615 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* array.c (rb_ary_sample): improve performance when many samples
from a large array. based on the patch by tomoya ishida
<tomoyapenguin AT gmail.com> in [ruby-dev:49956]. [Bug #13136]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57380 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
The current documentation for Array#join does not mention the
special treatment of nested arrays.
It says:
> Returns a string created by converting each element of the
> array to a string, separated by the given separator.
Expected behavior according to the docs would be:
[ "a", [1, 2, [:x, :y]], "b" ].join("-") #=> "a-[1, 2, [:x, :y]]-b"
# because of:
[1, 2, [:x, :y]].to_s #=> "[1, 2, [:x, :y]]"
Actual behavior:
[ "a", [1, 2, [:x, :y]], "b" ].join("-") #=> "a-1-2-x-y-b"
because join is applied recursively for nested arrays.
The patch clarifies this behavior.
(Also: small markup and grammar fix.)
Patch by Marcus Stollsteimer <sto.mar@web.de>
[ruby-talk:437238] [ruby-core:79079] [Bug #13130]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57329 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Shrinking the Array from the block invoked by Array#select! or
Array#reject! causes the Array to be a negative number size. Ensure that
the resulting Array won't be smaller than 0.
[ruby-core:78739] [Bug #13053]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57121 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Since the Array may be modified during rb_yield(), the length before
invoking the block can't be trusted. Fix possible out-of-bounds read in
Array#combination and Array#repeated_combination.
It may better to make a defensive copy of the Array, but for now let's
follow what Array#permutation does. [ruby-core:78738] [Bug #13052]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57119 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* array.c (rb_ary_sum): change the algorithm to Kahan-Babuska balancing
summation to be more precise.
[Feature #12871] [ruby-core:77771]
* enum.c (sum_iter, enum_sum): ditto.
* test_array.rb, test_enum.rb: add an assertion for the above change.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57001 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
The sentence `Negative values of +index+ count from the end of the array.` can be interpreted that it only holds if a block is given. Clarify it.
Patch by: Lukas Elmer <lukas.elmer@gmail.com> (@lukaselmer)
Signed-off-by: Akira Matsuda <ronnie@dio.jp>
closes#1472
[ci skip]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56679 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* array.c, class.c: Fixed documentation where Fixnum was referred
directly to use Integer, as Fixnum and Bignum are now unified
into Integer and direct usage is deprecated. [Fix GH-1459]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56382 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
a hash value of Object might be Bignum, but it causes many troubles
expecially the Object is used as a key of a hash. so I've gave up
to do so.
* array.c (rb_ary_hash): use above macro.
* bignum.c (rb_big_hash): ditto.
* hash.c (rb_obj_hash, rb_hash_hash): ditto.
* numeric.c (rb_dbl_hash): ditto.
* proc.c (proc_hash): ditto.
* re.c (rb_reg_hash, match_hash): ditto.
* string.c (rb_str_hash_m): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56340 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* array.c (rb_ary_dig): [DOC] update an example of error message
by Array#dig, because of Integer Unification. [Fix GH-1455]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56337 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
because rb_class_of may return a singleton class.
[ruby-dev:49781] [Bug #12738]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56111 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* array.c (rb_ary_concat_multi): take multiple arguments. based
on the patch by Satoru Horie. [Feature #12333]
* string.c (rb_str_concat_multi, rb_str_prepend_multi): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56021 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* array.c (rb_ary_splice): consider elements in middle of self.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55983 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* array.c (rb_ary_splice): use pointer and length pair instead of
an array object to replace.
* array.c (rb_ary_insert): get rid of creating temporary array.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55977 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* hash.c (rb_hash_add_new_element): add new element or do nothing
if it is contained already.
* array.c (ary_add_hash, ary_add_hash_by): use
rb_hash_add_new_element.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55707 b2dd03c8-39d4-4d8f-98ff-823fe69b080e