Ruby Issue Tracking System: Issueshttps://redmine.ruby-lang.org/https://redmine.ruby-lang.org/favicon.ico?17113305112017-01-31T14:05:49ZRuby Issue Tracking System
Redmine Ruby master - Feature #13174 (Open): Smaller id_table on 64bit platformhttps://redmine.ruby-lang.org/issues/131742017-01-31T14:05:49Zfunny_falcon (Yura Sokolov)funny.falcon@gmail.com
<p>Reduce size of id_table by 25% on 64bit platform (19% on smallest table):</p>
<ul>
<li>embed collision bit into key</li>
<li>use array of keys + array of values instead of array of struct item_t.<br>
Both arrays allocated at once, and pointer to values is calculated.</li>
</ul>
<p>Additional changes:</p>
<ul>
<li>stricter check in next_id_base.<br>
One bit is needed for collision check on 64bit platform.<br>
Range is more limited on 32bit platform with ID_SCOPE_SHIFT and RUBY_SPECIAL_SHIFT.</li>
<li>stricter check for result of next_id_base.<br>
Rais exception in rb_sym2id, assert in rb_make_internal_id.</li>
<li>allow to shrink id_table.<br>
Shrink was disabled for mix_table cause it leads to error in id_table type<br>
detection. Since mix_table were removed, it is safe to shrink it again.</li>
<li>improve large table performance by mixin higher bits into step value.</li>
</ul>
<p>Performance of small tables almost the same.<br>
Mixing higher bits takes 1-2% for small tables on hit, but improves large table<br>
performance.</p>
<p>Report: <a href="https://gist.github.com/funny-falcon/7a1af6b3891ae636b12237f25eb20690" class="external">https://gist.github.com/funny-falcon/7a1af6b3891ae636b12237f25eb20690</a></p>
<p><a href="https://github.com/funny-falcon/ruby/tree/smaller_id_table" class="external">https://github.com/funny-falcon/ruby/tree/smaller_id_table</a><br>
<a href="https://github.com/ruby/ruby/compare/trunk...funny-falcon:smaller_id_table.patch" class="external">https://github.com/ruby/ruby/compare/trunk...funny-falcon:smaller_id_table.patch</a></p> Ruby master - Bug #13019 (Closed): Fix st_hash* functionshttps://redmine.ruby-lang.org/issues/130192016-12-09T14:02:52Zfunny_falcon (Yura Sokolov)funny.falcon@gmail.com
<p>Previous implementation had an issues:</p>
<ul>
<li>macros murmur1 assumes murmur_step takes rotation value<br>
as a second argument</li>
<li>but murmur_step second argument is "next block"</li>
<li>this makes st_hash_uint and st_hash_end to not mix high bits of<br>
hash value into lower bits</li>
<li>this leads to pure hash behavior on doubles and mixing hashes using st_hash_uint.<br>
It didn't matter when bins amount were prime numbers, but it hurts<br>
when bins are powers of two.</li>
</ul>
<p>Mistake were created cause of attempt to co-exist Murmur1 and Murmur2<br>
in a same code.</p>
<p>Change it to single hash-function implementation.</p>
<ul>
<li>block function is in a spirit of Murmur functions,<br>
but handles inter-block dependency a bit better (imho).</li>
<li>final block is read in bit more optimal way on CPU with unaligned word access,</li>
<li>final block is mixed in simple way,</li>
<li>finalizer is taken from MurmurHash3 (it makes most of magic :) )<br>
(64bit finalizer is taken from<br>
<a href="http://zimbry.blogspot.ru/2011/09/better-bit-mixing-improving-on.html" class="external">http://zimbry.blogspot.ru/2011/09/better-bit-mixing-improving-on.html</a>)</li>
</ul>
<p>Also remove ST_USE_FNV1: it lacks implementation of many functions,<br>
and looks to be abandoned</p> Ruby master - Feature #13017 (Closed): Switch SipHash from SipHash24 to SipHash13https://redmine.ruby-lang.org/issues/130172016-12-08T17:36:58Zfunny_falcon (Yura Sokolov)funny.falcon@gmail.com
<p>SipHash13 is secure enough to be used in hash-tables, and SipHash's author confirms that.<br>
Rust already considered switch to SipHash13:<br>
<a href="https://github.com/rust-lang/rust/issues/29754#issue-116174313" class="external">https://github.com/rust-lang/rust/issues/29754#issue-116174313</a><br>
Jean-Philippe Aumasson confirmation:<br>
<a href="https://github.com/rust-lang/rust/issues/29754#issuecomment-156073946" class="external">https://github.com/rust-lang/rust/issues/29754#issuecomment-156073946</a><br>
Merged pull request:<br>
<a href="https://github.com/rust-lang/rust/pull/33940" class="external">https://github.com/rust-lang/rust/pull/33940</a></p>
<p>Github pull request <a href="https://github.com/ruby/ruby/pull/1501" class="external">https://github.com/ruby/ruby/pull/1501</a></p> Ruby master - Bug #12893 (Closed): trunk fails on linux with clang on test with callcchttps://redmine.ruby-lang.org/issues/128932016-11-03T18:30:54Zfunny_falcon (Yura Sokolov)funny.falcon@gmail.com
<p>Test fails on linux with clang.<br>
It doesn't fails with gcc.</p>
<p>OS: Ubuntu 16.04 x64_64<br>
clang version 3.8.0-2ubuntu4 (tags/RELEASE_380/final)<br>
configure: <code>../configure CC=clang CXX=clang++</code><br>
test:</p>
<p>$ make test-all TESTS='-n /callcc/'<br>
....<br>
Run options: "--ruby=./miniruby -I../lib -I. -I.ext/common ../tool/runruby.rb --extout=.ext -- --disable-gems" --excludes-dir=../test/excludes --name=!/memory_leak/ -n /callcc/</p>
<a name="Running-tests"></a>
<h1 >Running tests:<a href="#Running-tests" class="wiki-anchor">¶</a></h1>
<p>[ 1/18] TestArray#test_combination_with_callcc/home/yura/Project/ruby-falcon/test/ruby/test_array.rb:948: [BUG] Segmentation fault at 0x00000000000012<br>
ruby 2.4.0dev (2016-11-03 trunk 56550) [x86_64-linux]</p>
<p>-- Control frame information -----------------------------------------------<br>
c:0027 p:---- s:0155 e:000154 CFUNC :callcc<br>
c:0026 p:0016 s:0151 E:001310 BLOCK /home/yura/Project/ruby-falcon/test/ruby/test_array.rb:948 [FINISH]<br>
c:0025 p:---- s:0148 e:000147 CFUNC :combination<br>
c:0024 p:0038 s:0143 E:0021a0 METHOD /home/yura/Project/ruby-falcon/test/ruby/test_array.rb:947<br>
c:0023 p:0036 s:0135 E:000110 METHOD /home/yura/Project/ruby-falcon/test/lib/test/unit.rb:1029<br>
....<br>
-- Ruby level backtrace information ----------------------------------------<br>
....<br>
/home/yura/Project/ruby-falcon/test/lib/test/unit.rb:1029:in <code>run_test' /home/yura/Project/ruby-falcon/test/ruby/test_array.rb:947:in </code>test_combination_with_callcc'<br>
/home/yura/Project/ruby-falcon/test/ruby/test_array.rb:947:in <code>combination' /home/yura/Project/ruby-falcon/test/ruby/test_array.rb:948:in </code>block in test_combination_with_callcc'<br>
/home/yura/Project/ruby-falcon/test/ruby/test_array.rb:948:in `callcc'</p>
<p>-- Machine register context ------------------------------------------------<br>
RIP: 0x0000559aac7459b3 RBP: 0x00007ffd612aeb40 RSP: 0x00007ffd612aeaf0<br>
RAX: 0x0000000000000001 RBX: 0x0000559ab4745a50 RCX: 0x00007ffd612aeb3f<br>
RDX: 0x0000000000000002 RDI: 0x00007ffd612b1000 RSI: 0x0000559ab47765c0<br>
R8: 0x00007fee67cc4b00 R9: 0x0000559aac744b00 R10: 0x00007fee67cc4b00<br>
R11: 0x0000000000000020 R12: 0x0000000000000000 R13: 0x0000559ab4745a50<br>
R14: 0x0000000000000000 R15: 0x0000559aad43b5c0 EFL: 0x0000000000010202</p>
<p>-- C level backtrace information -------------------------------------------<br>
/home/yura/Project/ruby-falcon/.bld-clang~/ruby(rb_vm_bugreport+0x1cd) [0x559aac76652d] ../vm_dump.c:679<br>
/home/yura/Project/ruby-falcon/.bld-clang~/ruby(rb_bug_context+0x1e6) [0x559aac759466] ../error.c:426<br>
/home/yura/Project/ruby-falcon/.bld-clang~/ruby(sigsegv+0x4f) [0x559aac67717f] ../signal.c:897<br>
/lib/x86_64-linux-gnu/libpthread.so.0 [0x7fee678b93e0]<br>
/home/yura/Project/ruby-falcon/.bld-clang~/ruby(cont_capture+0x303) [0x559aac7459b3] ../cont.c:514<br>
/home/yura/Project/ruby-falcon/.bld-clang~/ruby(rb_callcc+0xe) [0x559aac744dbe] ../cont.c:949<br>
/home/yura/Project/ruby-falcon/.bld-clang~/ruby(vm_call_cfunc+0xf1) [0x559aac6e70c1] ../vm_insnhelper.c:1752<br>
/home/yura/Project/ruby-falcon/.bld-clang~/ruby(vm_exec_core+0x27fe) [0x559aac6d0fee] ../insns.def:967<br>
/home/yura/Project/ruby-falcon/.bld-clang~/ruby(vm_exec+0x9d) [0x559aac6e186d] ../vm.c:1711<br>
/home/yura/Project/ruby-falcon/.bld-clang~/ruby(invoke_block_from_c_splattable+0x158) [0x559aac6ef6d8] ../vm.c:1032<br>
/home/yura/Project/ruby-falcon/.bld-clang~/ruby(rb_yield+0x8a) [0x559aac6dc62a] ../vm.c:1069<br>
/home/yura/Project/ruby-falcon/.bld-clang~/ruby(yield_indexed_values+0x197) [0x559aac708857] ../array.c:4970<br>
/home/yura/Project/ruby-falcon/.bld-clang~/ruby(rb_ary_combination+0x3d7) [0x559aac704e47] ../array.c:5137<br>
/home/yura/Project/ruby-falcon/.bld-clang~/ruby(vm_call_cfunc+0xf1) [0x559aac6e70c1] ../vm_insnhelper.c:1752<br>
/home/yura/Project/ruby-falcon/.bld-clang~/ruby(vm_exec_core+0x27fe) [0x559aac6d0fee] ../insns.def:967<br>
/home/yura/Project/ruby-falcon/.bld-clang~/ruby(vm_exec+0x9d) [0x559aac6e186d] ../vm.c:1711<br>
/home/yura/Project/ruby-falcon/.bld-clang~/ruby(invoke_block_from_c_splattable+0x158) [0x559aac6ef6d8] ../vm.c:1032<br>
/home/yura/Project/ruby-falcon/.bld-clang~/ruby(rb_yield+0x8a) [0x559aac6dc62a] ../vm.c:1069<br>
/home/yura/Project/ruby-falcon/.bld-clang~/ruby(rb_ary_collect+0x229) [0x559aac6ff5c9] ../array.c:2732</p> Ruby master - Feature #12180 (Closed): switch id_table.c varianthttps://redmine.ruby-lang.org/issues/121802016-03-15T18:51:12Zfunny_falcon (Yura Sokolov)funny.falcon@gmail.com
<p>Currently used variant is 'binary search in small table + hash for large tables'.<br>
But for contemporary CPU it may be better to do linear scan for small tables.</p>
<p>It is already implemented in <code>id_table.c</code> and numbered as 35.</p>
<p>Tested with simple Redmine installation on Intel Haswell i7-4770 CPU @ 3.40GHz</p>
<ul>
<li>trunk:<br>
<code>Requests per second: 27.79 [#/sec] (mean)</code>
</li>
<li>with switched implementation:<br>
<code>Requests per second: 28.87 [#/sec] (mean)</code>
</li>
</ul> Ruby master - Bug #10923 (Closed): Bug in io/wait/wait.chttps://redmine.ruby-lang.org/issues/109232015-03-01T14:24:22Zfunny_falcon (Yura Sokolov)funny.falcon@gmail.com
<p><a href="https://github.com/ruby/ruby/blob/28b9f11d5a4b878adb50a3e5472ceea8c462ed4a/ext/io/wait/wait.c#L64-L65" class="external">https://github.com/ruby/ruby/blob/28b9f11d5a4b878adb50a3e5472ceea8c462ed4a/ext/io/wait/wait.c#L64-L65</a><br>
return value should be wrapped by INT2FIX</p> Ruby master - Feature #10585 (Open): struct: speedup struct.attr = v for first 10 attributes and ...https://redmine.ruby-lang.org/issues/105852014-12-10T14:41:30Zfunny_falcon (Yura Sokolov)funny.falcon@gmail.com
<p>0001 - Define optimized setters for first 10 attributes.</p>
<p>0002 - Cache members definition in an subclasses - it is safe cause it could be modified/overloaded.<br>
And use <code>rb_attr_get</code> to lookup definition - it is safe cause result is checked later and <code>Qnil</code> is treated as error.</p>
<p>0003,0004 - Use custom hash structure (on top of Array) to lookup members index in a big structure.<br>
Well, I doubt that big structures are useful, so I will not grieve if 0004 is not accepted.</p> Ruby master - Feature #8985 (Closed): xwillfree - promise to free memoryhttps://redmine.ruby-lang.org/issues/89852013-10-04T20:38:08Zfunny_falcon (Yura Sokolov)funny.falcon@gmail.com
<p>This patch changes semantic of RUBY_GC_MALLOC_LIMIT.<br>
Instead of being "periodical trigger" it becomes more like "safety trigger"<br>
which fires in allocation increase (instead of allocation amount).<br>
So that there is less need to tune RUBY_GC_MALLOC_LIMIT at all, and default<br>
8Mb becomes meaningful.</p>
<p>Before GC relaxation in commit 8c0033a make check ran 13% faster<br>
(292s instead of 338s) and doesn't seems to use more memory. It is now<br>
runs at the same speed, but I propose to revert some part of GC<br>
relaxation.</p>
<p>Tradeoffs for patch simplicity:</p>
<ul>
<li>it is not exact: only String, Array, Object, Struct, Bignum and Time are handled</li>
<li>only one function (xwillfree) introduced. Perhaps, more readable api could be useful.</li>
<li>xwillfree exposed to the public (ruby.h). Perhaps, it should be in an internal.h,<br>
but st.c doesn't include internal.h.<br>
And may be it could be useful for extensions.</li>
</ul>
<p><a href="https://github.com/ruby/ruby/pull/414" class="external">https://github.com/ruby/ruby/pull/414</a><br>
<a href="https://github.com/ruby/ruby/pull/414.patch" class="external">https://github.com/ruby/ruby/pull/414.patch</a><br>
<a href="https://github.com/ruby/ruby/pull/414.diff" class="external">https://github.com/ruby/ruby/pull/414.diff</a></p> Ruby master - Bug #8312 (Closed): Fix weird performance of Hash#shifthttps://redmine.ruby-lang.org/issues/83122013-04-23T23:45:27Zfunny_falcon (Yura Sokolov)funny.falcon@gmail.com
<p>rb_hash_shift has an optimization for case when #shift is called outside hash iteration.<br>
But in fact it is deoptimization, cause it uses rb_hash_foreach, which initiate safe<br>
iteration, so that deletion is delayed and whole hash traversing is done.</p>
<p>Fix simplifies code by doing same thing in both case: is there outer iteration or not.</p>
<p>Fix and benchmark is here: <a href="https://gist.github.com/funny-falcon/5444091" class="external">https://gist.github.com/funny-falcon/5444091</a></p>
<p>Benchmark results:</p>
<pre><code>before fix:
user system total real
Hash#shift 2.810000 0.000000 2.810000 ( 2.812111)
Hash#custom_shift 0.030000 0.000000 0.030000 ( 0.034924)
after fix:
user system total real
Hash#shift 0.010000 0.000000 0.010000 ( 0.019124)
Hash#custom_shift 0.030000 0.000000 0.030000 ( 0.033300)
</code></pre>
<p>patch is attached to issue as well.</p>
<p>This fix should be backported to 1.9.3 and 2.0.0 as well, cause it highly affects<br>
on Hash's usability as LRU cache.</p> Ruby master - Feature #8259 (Open): Atomic attributes accessorshttps://redmine.ruby-lang.org/issues/82592013-04-12T17:43:20Zfunny_falcon (Yura Sokolov)funny.falcon@gmail.com
<p>Motivated by this gist ((<a href="URL:https://gist.github.com/jstorimer/5298581" class="external">URL:https://gist.github.com/jstorimer/5298581</a>)) and atomic gem</p>
<p>I propose Class.attr_atomic which will add methods for atomic swap and CAS:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"> <span class="k">class</span> <span class="nc">MyNode</span>
<span class="nb">attr_accessor</span> <span class="ss">:item</span>
<span class="n">attr_atomic</span> <span class="ss">:successor</span>
<span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">item</span><span class="p">,</span> <span class="n">successor</span><span class="p">)</span>
<span class="vi">@item</span> <span class="o">=</span> <span class="n">item</span>
<span class="vi">@successor</span> <span class="o">=</span> <span class="n">successor</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">node</span> <span class="o">=</span> <span class="no">MyNode</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">other_node</span><span class="p">)</span>
<span class="c1"># attr_atomic ensures at least #{attr} reader method exists. May be, it should</span>
<span class="c1"># be sure it does volatile access.</span>
<span class="n">node</span><span class="p">.</span><span class="nf">successor</span>
<span class="c1"># #{attr}_cas(old_value, new_value) do CAS: atomic compare and swap</span>
<span class="k">if</span> <span class="n">node</span><span class="p">.</span><span class="nf">successor_cas</span><span class="p">(</span><span class="n">other_node</span><span class="p">,</span> <span class="n">new_node</span><span class="p">)</span>
<span class="nb">print</span> <span class="s2">"there were no interleaving with other threads"</span>
<span class="k">end</span>
<span class="c1"># #{attr}_swap atomically swaps value and returns old value.</span>
<span class="c1"># It ensures that no other thread interleaves getting old value and setting</span>
<span class="c1"># new one by cas (or other primitive if exists, like in Java 8)</span>
<span class="n">node</span><span class="p">.</span><span class="nf">successor_swap</span><span class="p">(</span><span class="n">new_node</span><span class="p">)</span>
</code></pre>
<p>It will be very simple for MRI cause of GIL, and it will use atomic primitives for<br>
other implementations.</p>
<p>Note: both (({#{attr}_swap})) and (({#{attr}_cas})) should raise an error if instance variable were not explicitly set before.</p>
<p>Example for nonblocking queue: ((<a href="URL:https://gist.github.com/funny-falcon/5370416" class="external">URL:https://gist.github.com/funny-falcon/5370416</a>))</p>
<p>Something similar should be proposed for Structs. May be override same method as (({Struct.attr_atomic}))</p>
<p>Open question for reader:<br>
should (({attr_atomic :my_attr})) ensure that #my_attr reader method exists?<br>
Should it guarantee that (({#my_attr})) provides 'volatile' access?<br>
May be, (({attr_reader :my_attr})) already ought to provide 'volatile' semantic?<br>
May be, semantic of (({@my_attr})) should have volatile semantic (i doubt for that)?</p> Ruby master - Feature #8158 (Closed): lightweight structure for loaded features indexhttps://redmine.ruby-lang.org/issues/81582013-03-24T16:56:23Zfunny_falcon (Yura Sokolov)funny.falcon@gmail.com
<p>Use lightweight structure for loaded_features index:</p>
<ul>
<li>use hand made simple hash structure, which uses only one memory chunk,</li>
<li>do not store feature name string, only hash of it, since loaded_feature_path<br>
will recheck feature name on hash collision</li>
<li>use single linked lists instead of arrays for storing features indices.</li>
<li>store this lists inside one array, using array's indices as a reference.</li>
</ul>
<p>While startup speedup improvement is relatively small compared current implementation,<br>
this one does not need any Ruby Objects at all, so that there is no presure on GC.</p>
<p><a href="https://github.com/ruby/ruby/pull/264.patch" class="external">https://github.com/ruby/ruby/pull/264.patch</a><br>
<a href="https://github.com/ruby/ruby/pull/264.diff" class="external">https://github.com/ruby/ruby/pull/264.diff</a><br>
<a href="https://github.com/ruby/ruby/pull/264" class="external">https://github.com/ruby/ruby/pull/264</a></p> Ruby master - Bug #7478 (Rejected): Do not include vararg.h - always include stdarg.hhttps://redmine.ruby-lang.org/issues/74782012-11-30T17:43:40Zfunny_falcon (Yura Sokolov)funny.falcon@gmail.com
<p>Cause : <a href="https://gist.github.com/4172330" class="external">https://gist.github.com/4172330</a></p>
<p>It seems that stdarg.h is included in many separate C files unconditionally:<br>
array.c, class.c, error.c, sprintf.c, include/ruby/ruby.h, include/ruby/encoding.h - all includes stdarg.h without checking for HAVE_STDARG_PROTOTYPES</p>
<p>So that, why there is check in include/ruby/intern.h, vm_core.h, vsnprintf.c (and may be somewhere else)</p> Ruby master - Bug #7383 (Closed): Use stricter cache check in load.chttps://redmine.ruby-lang.org/issues/73832012-11-18T19:09:51Zfunny_falcon (Yura Sokolov)funny.falcon@gmail.com
<p>rb_ary_shared_with_p does not react when #shift or #pop is called on original array.</p>
<p>This patch introduce rb_ary_dup_of_p , which makes more adequate check for duplicate<br>
of array.</p>
<p><a href="https://github.com/ruby/ruby/pull/216" class="external">https://github.com/ruby/ruby/pull/216</a><br>
<a href="https://github.com/ruby/ruby/pull/216.patch" class="external">https://github.com/ruby/ruby/pull/216.patch</a></p> Ruby master - Feature #6962 (Closed): Use lighter hash structure for methods table, instance vari...https://redmine.ruby-lang.org/issues/69622012-09-02T21:59:37Zfunny_falcon (Yura Sokolov)funny.falcon@gmail.com
<p>I've experimented with replacing <code>struct st_table</code> with lighter hash structure.</p>
<p>I were inspired by Lua tables, so that hash were created similar:</p>
<ul>
<li>open addressing but with elements chaining instead of any kind of probing</li>
<li>there is sibling probing on insert, to ensure cache locality</li>
<li>on insert, already inserted collision item which is not in main position is moved to free place,<br>
so that chains started from different main positions are not joined.<br>
This allows to keep chains short.</li>
<li>struct header is 24 bytes on 64bit platform (compared with 40 bytes for <code>st_table</code>), so that i've<br>
placed them directly into <code>rb_classext_struct</code> instead of separate allocation.</li>
</ul>
<p>Since keys are integers (ID), there is no separate field for hash. And I used <code>unsigned int</code> instead of<br>
<code>unsigned long</code> for key, cause ID almost never reach 2**32. It allows to pack whole entry into 16 bytes<br>
on 64bit platform (compared to 48 bytes for <code>st_table_entry</code>).</p>
<p>Such structure gives about 6% improvement without GC tuning, and 10% improvement when GC is tuned<br>
(I've used <code>RUBY_GC_MALLOC_LIMIT=60000000 RUBY_FREE_MIN=200000</code>)</p>
<p>Also I add per class method cache instead of single global hash array. It has advantage over global<br>
cache cause there is no collision over different classes and methods. But it seems that Rails applications<br>
too often creates singleton classes, so that improvement is not very big (but no slowdown too).</p>
<p>Currently I have patch for Ruby 1.9.3 <a href="https://github.com/funny-falcon/ruby/compare/ruby_1_9_3...sparse_array/ruby_1_9_3" class="external">https://github.com/funny-falcon/ruby/compare/ruby_1_9_3...sparse_array/ruby_1_9_3</a></p>
<p>Single incompatible external api change is almost neglible, cause <code>rb_generic_ivar_table</code> methos is not very usefull<br>
<a href="https://github.com/funny-falcon/ruby/compare/ruby_1_9_3...sparse_array/ruby_1_9_3#L5L852" class="external">https://github.com/funny-falcon/ruby/compare/ruby_1_9_3...sparse_array/ruby_1_9_3#L5L852</a></p>
<p>Silly, but there is too many changes in trunk, so that, I could not simply rebase it, but ought to make whole work again.<br>
I'll try to do it shortly.</p>
<p>With regards, Sokolov Yura aka funny-falcon.</p> Ruby master - Bug #6664 (Rejected): Object finalizer do not run until program exithttps://redmine.ruby-lang.org/issues/66642012-06-28T17:24:46Zfunny_falcon (Yura Sokolov)funny.falcon@gmail.com
<p>Test script: <a href="https://gist.github.com/3009867" class="external">https://gist.github.com/3009867</a></p>
<p>Conclusions:</p>
<ul>
<li>Ruby 1.8.7 (REE) is able to run finalizer on GC when its proc is created outside of scope and so that does not handle object in its binding.</li>
<li>even Ruby 1.8.7 not able to run finalizer until program exit when finalizer's proc is created in scope where #define_finalizer is called</li>
<li>neither Ruby 1.9.2, nor Ruby 1.9.3, nor Ruby-trunk is able to run finalizer until program exit.</li>
</ul> Ruby master - Feature #6638 (Closed): Array as queuehttps://redmine.ruby-lang.org/issues/66382012-06-24T16:41:35Zfunny_falcon (Yura Sokolov)funny.falcon@gmail.com
<p>Many libraries use Array as queue (cause stdlib has no real dequeue class).<br>
And typical pattern is to use #push and #shift methods with small count of #push<br>
with following small count of #shift.</p>
<p>But currently big array makes a copy every time array is modified after #shift,<br>
so that it degrades greatly when Array size growths.</p>
<p>Ironically, usage of #unshift with following #pop degrades much less, but most<br>
libraries doesn't consider this fact, and other ruby's implementations suffers<br>
from such pattern.</p>
<p>Test for 1.9.3 before patch: <a href="https://gist.github.com/2981959#file_test_before_patch" class="external">https://gist.github.com/2981959#file_test_before_patch</a></p>
<p>Main point of this patch is to change <code>rb_ary_modify</code> so that it considers ARY_SHARED_NUM<br>
and steel shared array pointer when ARY_SHARED_NUM == 1.<br>
To make it possible, it saves array's capa instead of array's length in <code>ary_make_shared</code><br>
and fixes rb_ary_sort_bang accordantly.</p>
<p>Test for 1.9.3 after patch: <a href="https://gist.github.com/2981959#file_test_after_patch" class="external">https://gist.github.com/2981959#file_test_after_patch</a><br>
(note that gain is less for ruby-trunk but still exists)</p>
<p>Pull request <a href="https://github.com/ruby/ruby/pull/133" class="external">https://github.com/ruby/ruby/pull/133</a><br>
Patch <a href="https://github.com/ruby/ruby/pull/133.patch" class="external">https://github.com/ruby/ruby/pull/133.patch</a></p>
<p>(but I think, despite the patch, Ruby needs real Deque in stdlib)</p> Ruby master - Feature #6199 (Closed): Organize gc.c a bithttps://redmine.ruby-lang.org/issues/61992012-03-25T08:07:31Zfunny_falcon (Yura Sokolov)funny.falcon@gmail.com
<ol>
<li>Move immutable fields from struct heaps_slot and struct sorted_heaps_slot into struct heaps_header.<br>
One exception is limit field, but it starts to be mutable just before freeing a heaps_header, so that it is not big issue.</li>
<li>Embed bitmap into struct heaps_slot</li>
<li>Change <code>free_unused_heaps</code> to <code>free_unused_heap</code>, so that it will not be called on every GC round, but only when page should be freed.<br>
While <code>free_unused_heaps</code> does not consume much time (it is invisible in profiler), but regular application has no need in calling this function every time.</li>
</ol>
<p><a href="https://github.com/ruby/ruby/pull/108" class="external">https://github.com/ruby/ruby/pull/108</a><br>
<a href="https://github.com/ruby/ruby/pull/108.patch" class="external">https://github.com/ruby/ruby/pull/108.patch</a></p> Ruby master - Bug #6174 (Rejected): Fix collision of ConditionVariable#wait timeout and #signal (...https://redmine.ruby-lang.org/issues/61742012-03-19T00:40:07Zfunny_falcon (Yura Sokolov)funny.falcon@gmail.com
<ol>
<li>Currently, when Thread wakes on timeout, it could not remove itself from ConditionVariable waiters until it acquires lock.<br>
So that, when ConditionVariable#signal is called, it will try to wakeup<br>
such thread, instead of some one else.<br>
<a href="https://github.com/funny-falcon/ruby/commit/24a9b6112477b2107ac9a19d0189a11fb97aa891" class="external">https://github.com/funny-falcon/ruby/commit/24a9b6112477b2107ac9a19d0189a11fb97aa891</a><br>
<a href="https://github.com/funny-falcon/ruby/commit/24a9b6112477b2107ac9a19d0189a11fb97aa891.patch" class="external">https://github.com/funny-falcon/ruby/commit/24a9b6112477b2107ac9a19d0189a11fb97aa891.patch</a>
</li>
</ol>
<p>Simple way to avoid it, is to allow Mutex#sleep to recieve a block, which will be called right after Thread will awake, but before Mutex will be tried to lock<br>
<a href="https://github.com/funny-falcon/ruby/commit/9e9157c5318926331dbe883416b69d38a58fea5d" class="external">https://github.com/funny-falcon/ruby/commit/9e9157c5318926331dbe883416b69d38a58fea5d</a><br>
<a href="https://github.com/funny-falcon/ruby/commit/9e9157c5318926331dbe883416b69d38a58fea5d.patch" class="external">https://github.com/funny-falcon/ruby/commit/9e9157c5318926331dbe883416b69d38a58fea5d.patch</a></p>
<ol start="2">
<li>
<p>Since MatzRuby use GVL for thread isolation, and native method could not be interrupted (unless it will), we could remove couple of calles to Mutex#synchronize<br>
<a href="https://github.com/funny-falcon/ruby/commit/a9ad8d274b96f14519643fc63327394f72b83516" class="external">https://github.com/funny-falcon/ruby/commit/a9ad8d274b96f14519643fc63327394f72b83516</a><br>
<a href="https://github.com/funny-falcon/ruby/commit/a9ad8d274b96f14519643fc63327394f72b83516.patch" class="external">https://github.com/funny-falcon/ruby/commit/a9ad8d274b96f14519643fc63327394f72b83516.patch</a></p>
</li>
<li>
<p>Usage of hash with <code>compare_by_identity</code> allows remove call to Array#include? in a Queue. Also it allows to remove other call Mutex#synchronize from ConditionVariable#wait in case when we rely on GVL.<br>
<a href="https://github.com/funny-falcon/ruby/commit/0da1887a04f7a0e4f9289d2167c2a6d0073651e1" class="external">https://github.com/funny-falcon/ruby/commit/0da1887a04f7a0e4f9289d2167c2a6d0073651e1</a><br>
<a href="https://github.com/funny-falcon/ruby/commit/0da1887a04f7a0e4f9289d2167c2a6d0073651e1.patch" class="external">https://github.com/funny-falcon/ruby/commit/0da1887a04f7a0e4f9289d2167c2a6d0073651e1.patch</a></p>
</li>
<li>
<p>And cosmetic changes to SizedQueue<br>
<a href="https://github.com/funny-falcon/ruby/commit/60ed97557c8178bc78edf670f3d53d761e627bf0" class="external">https://github.com/funny-falcon/ruby/commit/60ed97557c8178bc78edf670f3d53d761e627bf0</a><br>
<a href="https://github.com/funny-falcon/ruby/commit/60ed97557c8178bc78edf670f3d53d761e627bf0.patch" class="external">https://github.com/funny-falcon/ruby/commit/60ed97557c8178bc78edf670f3d53d761e627bf0.patch</a></p>
</li>
</ol>
<p>Pull request at once:<br>
<a href="https://github.com/ruby/ruby/pull/104" class="external">https://github.com/ruby/ruby/pull/104</a><br>
<a href="https://github.com/ruby/ruby/pull/104.diff" class="external">https://github.com/ruby/ruby/pull/104.diff</a><br>
<a href="https://github.com/ruby/ruby/pull/104.patch" class="external">https://github.com/ruby/ruby/pull/104.patch</a></p> Ruby master - Feature #6019 (Closed): Revision r34582 significantly slows down rails apphttps://redmine.ruby-lang.org/issues/60192012-02-14T19:13:34Zfunny_falcon (Yura Sokolov)funny.falcon@gmail.com
<p>Before r34582 simple rails32 app (query sqlite and disply 20 rows of simple data)<br>
benchmarked as 55req/second , after its performance is 33req/second.</p>
<p>I could agree that RubyOnRails should be in sync with ruby, but maybe there is other way<br>
to fix <code>respond_to?</code> ?</p> Ruby master - Bug #6006 (Closed): Fix calculation of HEAP_OBJ_LIMIT and HEAP_BITMAP_LIMIThttps://redmine.ruby-lang.org/issues/60062012-02-12T01:31:57Zfunny_falcon (Yura Sokolov)funny.falcon@gmail.com
<p><a href="https://github.com/ruby/ruby/pull/92" class="external">https://github.com/ruby/ruby/pull/92</a></p> Ruby master - Bug #5989 (Closed): Keyword spash is syntax error when there are no explicit keywor...https://redmine.ruby-lang.org/issues/59892012-02-09T14:15:54Zfunny_falcon (Yura Sokolov)funny.falcon@gmail.com
<pre><code>$ ruby -e 'def a(a:1, **h); p h; end; a(b: 1)'
{:b=>1}
$ ruby -e 'def a(**h); p h; end; a(b: 1)'
-e:1: syntax error, unexpected tPOW, expecting ')'
def a(**h); p h; end
^
</code></pre> Ruby master - Bug #5963 (Rejected): MacOS < 10.6 has no memalignhttps://redmine.ruby-lang.org/issues/59632012-02-03T15:02:21Zfunny_falcon (Yura Sokolov)funny.falcon@gmail.com
<p>I use definition of <code>aligned_malloc</code> from trunk in a st_pool_allocation patch for ruby_1_9_3,<br>
and I have report from a man who has OS X 10.5.8 , that there is such error:</p>
<p>pool_alloc.inc.h:55:2: error: #error no memalign function</p>
<p>It seems that OS X before 10.6 had no memalign or posix_memalign function.<br>
Possibly <code>valloc</code> could be used with similar HEAP_ALIGN_LOG determination as done for OpenBSD in <a href="http://bugs.ruby-lang.org/projects/ruby-trunk/repository/revisions/34404" class="external">http://bugs.ruby-lang.org/projects/ruby-trunk/repository/revisions/34404</a></p>
<p>As you can see, it is not possible to choose different version of MacOS here:<br>
<a href="https://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/posix_memalign.3.html" class="external">https://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/posix_memalign.3.html</a></p> Ruby master - Bug #5960 (Third Party's Issue): Error with rvm default gemset and rails rakehttps://redmine.ruby-lang.org/issues/59602012-02-03T04:39:47Zfunny_falcon (Yura Sokolov)funny.falcon@gmail.com
<p>After installing fresh ruby, creating fresh rails application, <code>rake db:migrate</code> fails with evident bug in requiring files<br>
(already created constants, files are required from <code>~/.rvm/gems/ruby-1.9.3-p0@global/gems/rake-0.9.2.2/lib/rake/</code> and from <code>~/.rvm/gems/ruby-1.9.3-p0/gems/rake-0.9.2.2/lib/rake/</code>)</p>
<p>Error disappeared when not default gemset is used.</p>
<p><a href="https://gist.github.com/1725184" class="external">https://gist.github.com/1725184</a></p> Ruby master - Bug #5946 (Rejected): Remove too early and unnecessary calls to heaps_incrementhttps://redmine.ruby-lang.org/issues/59462012-01-30T13:12:20Zfunny_falcon (Yura Sokolov)funny.falcon@gmail.com
<p>Too early call in <code>lazy_sweep</code> slows down sweep phase, cause while loop breaks on <code>if (has_free_object) { ... return TRUE;}</code> .</p>
<p>Heap expand in <code>gc_clear_mark_on_sweep_slots</code> unnecessary expands number of heaps, which slows down iterations in <code>rb_objspace_call_finalizer</code>, and <code>gc_marks</code> (cause we often need to binary search heap for pointer).</p>
<p>Testing suit: <a href="https://gist.github.com/1702301" class="external">https://gist.github.com/1702301</a></p>
<p>Before:</p>
<pre><code>$ sh siege.sh
Transaction rate: 114.71 trans/sec
Transaction rate: 117.84 trans/sec
Transaction rate: 121.62 trans/sec
$ sh siege.sh
Transaction rate: 118.72 trans/sec
Transaction rate: 120.32 trans/sec
Transaction rate: 121.12 trans/sec
</code></pre>
<p>After:</p>
<pre><code>$ sh siege.sh
Transaction rate: 121.62 trans/sec
Transaction rate: 122.12 trans/sec
Transaction rate: 123.12 trans/sec
$ sh siege.sh
Transaction rate: 123.25 trans/sec
Transaction rate: 121.94 trans/sec
Transaction rate: 123.52 trans/sec
</code></pre>
<p><a href="https://github.com/ruby/ruby/pull/89" class="external">https://github.com/ruby/ruby/pull/89</a></p> Backport193 - Backport #5942 (Rejected): Backport r34309-34310 r34312-32414https://redmine.ruby-lang.org/issues/59422012-01-29T16:33:22Zfunny_falcon (Yura Sokolov)funny.falcon@gmail.com
<p>I understand, that it is mostly imposible, but would you mind to backport changes of st.c,<br>
so that my patches to it against following versions of ruby 1.9.3 will be simpler.</p>
<p>Backporting diff attached.</p> Backport193 - Backport #5936 (Closed): Empty backportshttps://redmine.ruby-lang.org/issues/59362012-01-27T06:04:44Zfunny_falcon (Yura Sokolov)funny.falcon@gmail.com
<p>Is it intended that following revisions didn't change anything except Changelog and version.h ?</p>
<p><a href="http://bugs.ruby-lang.org/projects/ruby-193/repository/revisions/34275" class="external">http://bugs.ruby-lang.org/projects/ruby-193/repository/revisions/34275</a><br>
<a href="http://bugs.ruby-lang.org/projects/ruby-193/repository/revisions/34276" class="external">http://bugs.ruby-lang.org/projects/ruby-193/repository/revisions/34276</a><br>
<a href="http://bugs.ruby-lang.org/projects/ruby-193/repository/revisions/34274" class="external">http://bugs.ruby-lang.org/projects/ruby-193/repository/revisions/34274</a></p> Backport193 - Backport #5911 (Closed): File.expand_path produces malfunction string (it doesn't c...https://redmine.ruby-lang.org/issues/59112012-01-19T13:37:21Zfunny_falcon (Yura Sokolov)funny.falcon@gmail.com
<pre><code>ruby-1.9.3-p0 :018 > a = "/\u043f\u0440\u0438\u0432\u0435\u0442"
=> "/привет"
ruby-1.9.3-p0 :019 > a.bytes.to_a
=> [47, 208, 191, 209, 128, 208, 184, 208, 178, 208, 181, 209, 130]
ruby-1.9.3-p0 :020 > a.encoding
=> #<Encoding:UTF-8>
ruby-1.9.3-p0 :021 > b = a.encode('cp1251')
=> "/\xEF\xF0\xE8\xE2\xE5\xF2"
ruby-1.9.3-p0 :022 > b.bytes.to_a
=> [47, 239, 240, 232, 226, 229, 242]
ruby-1.9.3-p0 :023 > b.encoding
=> #<Encoding:Windows-1251>
ruby-1.9.3-p0 :024 > c = File.expand_path(b)
=> "/\xEF\xF0\xE8\xE2\xE5\xF2"
ruby-1.9.3-p0 :025 > c.bytes.to_a
=> [47, 239, 240, 232, 226, 229, 242]
ruby-1.9.3-p0 :026 > c.encoding
=> #<Encoding:Windows-1251>
ruby-1.9.3-p0 :027 > d = c.encode('utf-8')
=> "/\xEF\xF0\xE8\xE2\xE5\xF2"
ruby-1.9.3-p0 :028 > d.bytes.to_a
=> [47, 239, 240, 232, 226, 229, 242]
ruby-1.9.3-p0 :029 > d.encoding
=> #<Encoding:UTF-8>
ruby-1.9.3-p0 :030 > b == c
=> true
ruby-1.9.3-p0 :031 > a == d
=> false
ruby-1.9.3-p0 :032 > c.force_encoding(c.encoding)
=> "/\xEF\xF0\xE8\xE2\xE5\xF2"
ruby-1.9.3-p0 :033 > e = c.encode('utf-8')
=> "/привет"
ruby-1.9.3-p0 :034 > e.bytes.to_a
=> [47, 208, 191, 209, 128, 208, 184, 208, 178, 208, 181, 209, 130]
ruby-1.9.3-p0 :035 > e.encoding
=> #<Encoding:UTF-8>
ruby-1.9.3-p0 :036 > a == e
=> true
</code></pre>
<p>Initially I found this bug in Windows (with RubyInstaller).<br>
It confirmed in Linux with ruby installed by <code>rvm</code>,<br>
but not confirmed when I install same version from git repository to other path :(<br>
So that I think bug exists, but it is very hidden.</p> Backport193 - Backport #5909 (Closed): File.expand_path cases has no specs for some cases in Windowshttps://redmine.ruby-lang.org/issues/59092012-01-19T13:28:39Zfunny_falcon (Yura Sokolov)funny.falcon@gmail.com
<p>Following cases in file_expand_path has no tests.</p>
<p><a href="http://bugs.ruby-lang.org/projects/ruby-trunk/repository/revisions/34215/entry/file.c#L2926" class="external">http://bugs.ruby-lang.org/projects/ruby-trunk/repository/revisions/34215/entry/file.c#L2926</a></p>
<p>irb(main):014:0> Dir.pwd<br>
=> "C:/Ruby193/bin"<br>
irb(main):015:0> File.expand_path('C:asdf', 'D:\home')<br>
=> "C:/Ruby193/bin/asdf"<br>
irb(main):016:0> File.expand_path('C:asdf', 'C:\home')<br>
=> "C:/home/asdf"</p>
<p><a href="http://bugs.ruby-lang.org/projects/ruby-trunk/repository/revisions/34215/entry/file.c#L2969" class="external">http://bugs.ruby-lang.org/projects/ruby-trunk/repository/revisions/34215/entry/file.c#L2969</a></p>
<p>irb(main):019:0> Dir.pwd<br>
=> "C:/Ruby193/bin"<br>
irb(main):020:0> File.expand_path('\asdf')<br>
=> "C:/asdf"<br>
irb(main):021:0> File.expand_path('\asdf', 'D:\home')<br>
=> "D:/asdf"</p>
<p>This specs are desirable for testing experimental version of File.expand_path , which uses Windows API<br>
(fenix by Luis Lavena)</p> Ruby master - Feature #5903 (Closed): Optimize st_table (take 2)https://redmine.ruby-lang.org/issues/59032012-01-17T23:37:21Zfunny_falcon (Yura Sokolov)funny.falcon@gmail.com
<p>Given some of preparations to this patches already merged into ruby-trunk,<br>
I suggest patches for improving st_table second time (first were <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Optimize st_table (Closed)" href="https://redmine.ruby-lang.org/issues/5789">#5789</a>):</p>
<ol>
<li>Usage of packing for st_table of any kind, not only for numeric hashes.</li>
</ol>
<p>Most of hashes, allocated during page render in Rails are smaller than 6 entries.<br>
In fact, during rendering "Issues" page of Redmine, 40% of hashes not even grows<br>
above 1 entry. They are small options hashes, passed to numerous helper methods.</p>
<p>This patch packs hashes upto 6 entries in a way like numeric hashes from trunk.<br>
Also it pack hashes of size 0 and 1 into <code>st_table</code> inself, so that there is no<br>
need to allocate any "bins" at all.</p>
<p><a href="https://github.com/ruby/ruby/pull/84.patch" class="external">https://github.com/ruby/ruby/pull/84.patch</a><br>
<a href="https://github.com/ruby/ruby/pull/84" class="external">https://github.com/ruby/ruby/pull/84</a></p>
<ol start="2">
<li>Usage of specialized pool for allocating st_table, st_table_entry structures<br>
and st_table.bins of smallest size (11)</li>
</ol>
<p>Usage of specialized pool for this allocations give great speedup for hash creation.<br>
Also it gives countable reduction of memory consumption.</p>
<p><a href="https://github.com/ruby/ruby/pull/83.patch" class="external">https://github.com/ruby/ruby/pull/83.patch</a><br>
<a href="https://github.com/ruby/ruby/pull/83" class="external">https://github.com/ruby/ruby/pull/83</a></p>
<p>First patch gives little overhead for creating hashes bigger than 6 entries when applied alone.<br>
But both patches combined are not slower than ruby-trunk for hashes of any size.</p>
<p>Performance testing is here <a href="https://gist.github.com/1626602" class="external">https://gist.github.com/1626602</a></p> Ruby master - Feature #5875 (Closed): Couple of tiny changes to stringhttps://redmine.ruby-lang.org/issues/58752012-01-10T22:00:42Zfunny_falcon (Yura Sokolov)funny.falcon@gmail.com
<ul>
<li>change capacity increment from (capa + 1) * 2 to capa * 2 + 1<br>
previous increment formula leads to inconvenient allocation patterns: 25bytes, 51bytes, etc<br>
new formula leads to more comfortable allocation pattern: 24b, 48b, 96b</li>
<li>change STR_BUF_MIN_SIZE from 128 to 79<br>
128 leads to allocation of 129 bytes, which is very uncomfortable for allocators and unnecessary large.<br>
(during Redmine startup this method is called about 3000000 times with capa < 128)</li>
</ul>
<p><a href="https://github.com/ruby/ruby/pull/80" class="external">https://github.com/ruby/ruby/pull/80</a><br>
<a href="https://github.com/funny-falcon/ruby/commit/2240a04d49118d9fa6f038655dac27f0ad96ed6b.patch" class="external">https://github.com/funny-falcon/ruby/commit/2240a04d49118d9fa6f038655dac27f0ad96ed6b.patch</a></p> Ruby master - Feature #5789 (Closed): Optimize st_tablehttps://redmine.ruby-lang.org/issues/57892011-12-22T18:34:07Zfunny_falcon (Yura Sokolov)funny.falcon@gmail.com
<p>I prepared couple of patches to optimize st_table performance.</p>
<p>First patch (st_func.patch) is a trivial translation of some macroses to functions,<br>
but it gives ~4% of improvement on gcc-4.5.2 32bit (sorry for not testing other environments).</p>
<p>Second patch (st_pack_table) provides packing for tables sized upto 12 entries.<br>
It gives countable memory footprint reduction and measurable performance improvement<br>
(~8% compared to trunk, ~4% compared to st_func.patch).<br>
Note: synthetic benchmark could show some performance degradation, so that there<br>
could be some exotic workload, which suffer from patch.<br>
But realworld application (and even make check) runs uniformly faster.</p>
<p>Correlated github pull requests are <a href="https://github.com/ruby/ruby/pull/70" class="external">https://github.com/ruby/ruby/pull/70</a> and <a href="https://github.com/ruby/ruby/pull/71" class="external">https://github.com/ruby/ruby/pull/71</a></p> Ruby master - Feature #5767 (Closed): Cache expanded_load_path to reduce startup timehttps://redmine.ruby-lang.org/issues/57672011-12-15T18:18:29Zfunny_falcon (Yura Sokolov)funny.falcon@gmail.com
<p>This patch add caching of expanded load path.<br>
It reduces rails startup time by 33%<br>
(patch against 1.9.3-p0 and simple performance test is here <a href="https://gist.github.com/1480404" class="external">https://gist.github.com/1480404</a> )</p> Ruby master - Bug #5727 (Closed): Hidden bug in load.c rb_feature_phttps://redmine.ruby-lang.org/issues/57272011-12-08T16:15:29Zfunny_falcon (Yura Sokolov)funny.falcon@gmail.com
<p>lazy assigned load_path searched in loading_table were not expanded<br>
(<a href="http://redmine.ruby-lang.org/projects/ruby-trunk/repository/revisions/33027/entry/load.c#L186" class="external">http://redmine.ruby-lang.org/projects/ruby-trunk/repository/revisions/33027/entry/load.c#L186</a>),<br>
but all features, pushed to loading table, are expanded.</p>
<p>This bug is hidden because load_path is allways filled in loaded_features loop<br>
(<a href="http://redmine.ruby-lang.org/projects/ruby-trunk/repository/revisions/33027/entry/load.c#L160" class="external">http://redmine.ruby-lang.org/projects/ruby-trunk/repository/revisions/33027/entry/load.c#L160</a>),<br>
but if we try to optimize this loop (<a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Not complex patch to improve `require` time (load.c) (Closed)" href="https://redmine.ruby-lang.org/issues/5427">#5427</a>), then load_path could be not filled, and bug exposed.</p>
<p>(pull request on github <a href="https://github.com/ruby/ruby/pull/63" class="external">https://github.com/ruby/ruby/pull/63</a> )</p> Ruby master - Feature #5427 (Closed): Not complex patch to improve `require` time (load.c)https://redmine.ruby-lang.org/issues/54272011-10-09T17:49:50Zfunny_falcon (Yura Sokolov)funny.falcon@gmail.com
<p>Currently <code>loaded_features</code> are unsorted, so that <code>rb_feature_p</code> ought to iterate over all <code>loaded_features</code> to figure: is requested feature loaded?</p>
<p>After this patch <code>loaded_features</code> is kept sorted by basename without extension (/usr/lib/ruby/asdf.rb => asdf). When <code>rb_feature_p</code> start its check, it goes straight to the first item with matching basename (using binary search) and stops after last.</p>
<p>Methods <code>$LOADED_FEATURES.<<</code> and <code>$LOADED_FEATURES.push</code> are overriden to keep sort order. <code>push</code> accepts only 1 parameter, but it seems that no one pass more to it.</p>
<p>Currently I choose to consider characters of basename in right to left order, but it could be changed, I think.</p>
<p><a href="https://gist.github.com/1272991" class="external">https://gist.github.com/1272991</a><br>
<a href="https://github.com/ruby/ruby/pull/51" class="external">https://github.com/ruby/ruby/pull/51</a></p> Ruby master - Bug #3726 (Closed): require degradation from 1.9.1https://redmine.ruby-lang.org/issues/37262010-08-20T22:51:31Zfunny_falcon (Yura Sokolov)funny.falcon@gmail.com
<p>=begin<br>
I have two simultaneous installation of ruby 1.9.1 and ruby 1.9.2.<br>
There are installed gems ( pg in particular ).</p>
<p>Having file 5.rb containing</p>
<p>require 'pg'</p>
<p>i have following results:</p>
<p>For ruby 1.9.1:</p>
<a name="time-optruby191binruby19-5rb"></a>
<h1 >time /opt/ruby1.9.1/bin/ruby1.9 5.rb<a href="#time-optruby191binruby19-5rb" class="wiki-anchor">¶</a></h1>
<p>real 0m0.086s<br>
user 0m0.056s<br>
sys 0m0.008s</p>
<a name="time-optruby191binruby19-r-profile-5rb"></a>
<h1 >time /opt/ruby1.9.1/bin/ruby1.9 -r profile 5.rb<a href="#time-optruby191binruby19-r-profile-5rb" class="wiki-anchor">¶</a></h1>
<p>% cumulative self self total<br>
time seconds seconds calls ms/call ms/call name<br>
100.00 0.03 0.03 2 15.00 25.00 Kernel.require<br>
0.00 0.03 0.00 131 0.00 0.00 Module#method_added<br>
0.00 0.03 0.00 3 0.00 0.00 Class#inherited<br>
0.00 0.03 0.00 1 0.00 0.00 String#=~<br>
0.00 0.03 0.00 13 0.00 0.00 BasicObject#singleton_method_added<br>
0.00 0.03 0.00 4 0.00 0.00 IO#set_encoding<br>
0.00 0.03 0.00 1 0.00 30.00 #toplevel</p>
<p>real 0m0.116s<br>
user 0m0.076s<br>
sys 0m0.020s</p>
<p>For ruby 1.9.2:</p>
<a name="time-optruby192binruby19-5rb"></a>
<h1 >time /opt/ruby1.9.2/bin/ruby1.9 5.rb<a href="#time-optruby192binruby19-5rb" class="wiki-anchor">¶</a></h1>
<p>real 0m0.449s<br>
user 0m0.296s<br>
sys 0m0.048s</p>
<a name="time-optruby192binruby19-r-profile-5rb"></a>
<h1 >time /opt/ruby1.9.2/bin/ruby1.9 -r profile 5.rb<a href="#time-optruby192binruby19-r-profile-5rb" class="wiki-anchor">¶</a></h1>
<p>% cumulative self self total<br>
time seconds seconds calls ms/call ms/call name<br>
27.74 0.43 0.43 28 15.36 60.36 Kernel.gem_original_require<br>
5.16 0.51 0.08 3963 0.02 0.02 Hash#default<br>
5.16 0.59 0.08 45 1.78 7.33 Array#each<br>
4.52 0.66 0.07 287 0.24 0.42 String#gsub<br>
3.23 0.71 0.05 897 0.06 0.06 Module#===<br>
3.23 0.76 0.05 11 4.55 45.45 Gem::SourceIndex#load_specification<br>
3.23 0.81 0.05 371 0.13 0.24 Kernel.dup<br>
3.23 0.86 0.05 265 0.19 0.68 RbConfig.expand<br>
2.58 0.90 0.04 126 0.32 10.63 Class#new<br>
2.58 0.94 0.04 374 0.11 0.11 Kernel.initialize_dup<br>
2.58 0.98 0.04 605 0.07 0.07 Kernel.===<br>
1.94 1.01 0.03 585 0.05 0.05 Hash#[]=<br>
1.94 1.04 0.03 31 0.97 4.19 Gem::Requirement#initialize<br>
1.94 1.07 0.03 11 2.73 2.73 IO#read<br>
1.94 1.10 0.03 31 0.97 3.23 Array#map!<br>
1.29 1.12 0.02 531 0.04 0.04 Module#method_added<br>
1.29 1.14 0.02 27 0.74 85.93 Kernel.require<br>
1.29 1.16 0.02 363 0.06 0.06 Kernel.instance_variable_set<br>
1.29 1.18 0.02 59 0.34 0.34 String#scan<br>
1.29 1.20 0.02 64 0.31 0.63 Array#map<br>
1.29 1.22 0.02 21 0.95 1.43 Gem::Specification#attribute<br>
1.29 1.24 0.02 59 0.34 1.53 Gem::Version#initialize<br>
1.29 1.26 0.02 29 0.69 1.03 Array#select<br>
0.65 1.27 0.01 308 0.03 0.03 String#==<br>
0.65 1.28 0.01 159 0.06 0.06 String#to_i<br>
0.65 1.29 0.01 3 3.33 186.67 Mutex#synchronize<br>
0.65 1.30 0.01 26 0.38 0.38 Dir#[]<br>
0.65 1.31 0.01 59 0.17 0.34 Gem::Version#correct?<br>
0.65 1.32 0.01 1 10.00 10.00 Gem.ruby_engine<br>
0.65 1.33 0.01 71 0.14 0.14 String#=~<br>
0.65 1.34 0.01 2 5.00 5.00 Dir#glob<br>
0.65 1.35 0.01 40 0.25 0.25 Module#attr_accessor<br>
0.65 1.36 0.01 176 0.06 0.06 Regexp#=~<br>
0.65 1.37 0.01 9 1.11 1.11 Module#include<br>
0.65 1.38 0.01 8 1.25 1.25 Time#local<br>
0.65 1.39 0.01 100 0.10 0.10 Symbol#to_s<br>
0.65 1.40 0.01 8 1.25 1.25 Comparable.>=<br>
0.65 1.41 0.01 11 0.91 40.91 Kernel.eval<br>
0.65 1.42 0.01 47 0.21 0.21 Kernel.object_id<br>
0.65 1.43 0.01 18 0.56 1.67 Gem::GemPathSearcher#matching_files<br>
0.65 1.44 0.01 1 10.00 10.00 Gem::SourceIndex#search<br>
0.65 1.45 0.01 143 0.07 0.07 Hash#[]<br>
0.65 1.46 0.01 163 0.06 0.06 BasicObject#singleton_method_added<br>
0.00 1.46 0.00 3 0.00 0.00 Gem::Specification#original_name<br>
0.00 1.46 0.00 1 0.00 150.00 Hash#each_value<br>
0.00 1.46 0.00 1 0.00 0.00 Hash#merge!<br>
0.00 1.46 0.00 1 0.00 0.00 Mutex#initialize<br>
.......................................................<br>
0.00 1.46 0.00 1 0.00 0.00 Gem.load_path_insert_index<br>
0.00 1.46 0.00 1 0.00 0.00 Array#insert<br>
0.00 1.46 0.00 1 0.00 10.00 Gem.activate<br>
0.00 1.55 0.00 1 0.00 1550.00 #toplevel</p>
<p>real 0m2.215s<br>
user 0m1.656s<br>
sys 0m0.096s<br>
=end</p> Ruby master - Bug #602 (Closed): CGI::HtmlExtension::popup_menu calls #bytesize on array parametershttps://redmine.ruby-lang.org/issues/6022008-09-25T23:20:33Zfunny_falcon (Yura Sokolov)funny.falcon@gmail.com
<p>=begin<br>
After line 623<br>
values.collect{|value|<br>
if value.kind_of?(String)<br>
option({ "VALUE" => value }){ value }<br>
else</p>
<ul>
<li>
<pre><code> if value[value.bytesize - 1] == true
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> if value[value.size - 1] == true
option({ "VALUE" => value[0], "SELECTED" => true }){
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> value[value.bytesize - 2]
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> value[value.size - 2]
}
else
option({ "VALUE" => value[0] }){
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> value[value.bytesize - 1]
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> value[value.size - 1]
}
end
end
}.join
</code></pre>
</li>
</ul>
<p>=end</p>