Array#== walks both element buffers and only calls rb_equal() for a
pair whose VALUEs differ. Array#eql? called rb_ary_elt() twice and
rb_eql() once for every element, even though rb_eql() answers true
for identical VALUEs before doing anything else. For arrays of
Fixnums, Symbols, and nil, which are identical whenever they are
equal, that made eql? several times slower than ==.
recursive_eql() now walks the buffers the way recursive_equal() does.
A pair that is not identical still goes through rb_eql(), which can
run user code that resizes either array, so the length and both
buffers are re-read after every such call. Arrays whose lengths came
apart compare unequal, as they do under ==. Before, the shorter one
read as nil past its end, so the result depended on the remaining
elements of the longer one.
The new tests cover an element whose eql? empties both arrays,
shortens one of them, or grows both past their original capacity
mid-compare.