Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 11db41fdaf58
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 7cc6174dbc34
Choose a head ref
  • 3 commits
  • 4 files changed
  • 1 contributor

Commits on Aug 11, 2017

  1. cat Array#inspect start/end and separators directly as bytes

    ... this shows ~ 10-15% improvements on micro-benchmarks :
    
    ```
    Rehearsal --------------------------------------------------------------
    ['foo', 'bar'] [10000000x]   8.340000   0.110000   8.450000 (  6.625428)
    [1, 2, 3, 4] [10000000x]     8.370000   0.030000   8.400000 (  7.146743)
    [] [10000000x]               0.890000   0.010000   0.900000 (  0.783135)
    [:symbol] [10000000x]        3.990000   0.000000   3.990000 (  3.733776)
    ---------------------------------------------------- total: 21.740000sec
    
                                     user     system      total        real
    ['foo', 'bar'] [10000000x]   5.570000   0.000000   5.570000 (  5.568070)
    [1, 2, 3, 4] [10000000x]     6.700000   0.000000   6.700000 (  6.693513)
    [] [10000000x]               0.640000   0.000000   0.640000 (  0.634875)
    [:symbol] [10000000x]        3.610000   0.010000   3.620000 (  3.617086)
    ```
    
    AFTER :
    
    ```
    Rehearsal --------------------------------------------------------------
    ['foo', 'bar'] [10000000x]   7.380000   0.120000   7.500000 (  6.124045)
    [1, 2, 3, 4] [10000000x]     7.680000   0.060000   7.740000 (  6.580833)
    [] [10000000x]               0.820000   0.010000   0.830000 (  0.602847)
    [:symbol] [10000000x]        3.610000   0.010000   3.620000 (  3.323036)
    ---------------------------------------------------- total: 19.690000sec
    
                                     user     system      total        real
    ['foo', 'bar'] [10000000x]   5.100000   0.010000   5.110000 (  5.095054)
    [1, 2, 3, 4] [10000000x]     6.270000   0.000000   6.270000 (  6.237186)
    [] [10000000x]               0.710000   0.000000   0.710000 (  0.531142)
    [:symbol] [10000000x]        3.210000   0.000000   3.210000 (  3.202686)
    ```
    kares committed Aug 11, 2017
    Copy the full SHA
    6edfd90 View commit details
  2. Copy the full SHA
    b9fd647 View commit details
  3. Copy the full SHA
    7cc6174 View commit details
43 changes: 24 additions & 19 deletions core/src/main/java/org/jruby/RubyArray.java
Original file line number Diff line number Diff line change
@@ -98,7 +98,7 @@
* all users must synchronize externally with writers.
*
*/
@JRubyClass(name="Array")
@JRubyClass(name="Array", include = { "Enumerable" })
public class RubyArray extends RubyObject implements List, RandomAccess {
public static final int DEFAULT_INSPECT_STR_SIZE = 10;

@@ -1624,28 +1624,30 @@ public RubyArray concat19(IRubyObject obj) {
protected IRubyObject inspectAry(ThreadContext context) {
final Ruby runtime = context.runtime;
RubyString str = RubyString.newStringLight(runtime, DEFAULT_INSPECT_STR_SIZE, USASCIIEncoding.INSTANCE);
EncodingUtils.strBufCat(runtime, str, OPEN_BRACKET);
str.cat((byte) '[');
boolean tainted = isTaint();

for (int i = 0; i < realLength; i++) {

RubyString s = inspect(context, safeArrayRef(runtime, values, begin + i));
if (s.isTaint()) tainted = true;
if (i > 0) EncodingUtils.strBufCat(runtime, str, COMMA_SPACE);
else str.setEncoding(s.getEncoding());
if (i > 0) {
ByteList bytes = str.getByteList();
bytes.ensure(2 + s.size() + 1);
bytes.append((byte) ',').append((byte) ' ');
}
else {
str.setEncoding(s.getEncoding());
}
str.cat19(s);
}
EncodingUtils.strBufCat(runtime, str, CLOSE_BRACKET);
str.cat((byte) ']');

if (tainted) str.setTaint(true);

return str;
}

protected static final ByteList OPEN_BRACKET = new ByteList(new byte[]{(byte)'['}, USASCIIEncoding.INSTANCE);
protected static final ByteList CLOSE_BRACKET = new ByteList(new byte[]{(byte)']'}, USASCIIEncoding.INSTANCE);
protected static final ByteList COMMA_SPACE = new ByteList(new byte[]{(byte)',', (byte)' '}, USASCIIEncoding.INSTANCE);


/** rb_ary_inspect
*
*/
@@ -2022,17 +2024,13 @@ public IRubyObject checkArrayType(){
@JRubyMethod(name = "==", required = 1)
@Override
public IRubyObject op_equal(ThreadContext context, IRubyObject obj) {
Ruby runtime = context.runtime;

if (this == obj) {
return runtime.getTrue();
}
if (this == obj) return context.runtime.getTrue();

if (!(obj instanceof RubyArray)) {
if (obj == context.nil) return runtime.getFalse();
if (obj == context.nil) return context.runtime.getFalse();

if (!sites(context).respond_to_to_ary.respondsTo(context, obj, obj)) {
return runtime.getFalse();
return context.runtime.getFalse();
}
return Helpers.rbEqual(context, obj, this);
}
@@ -4996,8 +4994,6 @@ public int indexOf(Object element) {
}

public int lastIndexOf(Object element) {
int myBegin = 0;

if (element != null) {
IRubyObject convertedElement = JavaUtil.convertJavaToUsableRubyObject(getRuntime(), element);

@@ -5129,6 +5125,15 @@ public void clear() {
rb_clear();
}

@Override
public boolean equals(Object other) {
if (this == other) return true;
if (other instanceof RubyArray) {
return op_equal(getRuntime().getCurrentContext(), (RubyArray) other).isTrue();
}
return false;
}

private IRubyObject safeArrayRef(IRubyObject[] values, int i) {
return safeArrayRef(getRuntime(), values, i);
}
61 changes: 41 additions & 20 deletions core/src/main/java/org/jruby/RubyHash.java
Original file line number Diff line number Diff line change
@@ -54,6 +54,7 @@
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.runtime.marshal.MarshalStream;
import org.jruby.runtime.marshal.UnmarshalStream;
import org.jruby.util.ByteList;
import org.jruby.util.RecursiveComparator;
import org.jruby.util.TypeConverter;

@@ -755,12 +756,8 @@ private void checkDefaultProcArity(IRubyObject proc) {
/** rb_hash_set_default_proc
*
*/
public IRubyObject set_default_proc(IRubyObject proc) {
return set_default_proc20(proc);
}

@JRubyMethod(name = "default_proc=")
public IRubyObject set_default_proc20(IRubyObject proc) {
public IRubyObject set_default_proc(IRubyObject proc) {
modify();

if (proc.isNil()) {
@@ -770,7 +767,7 @@ public IRubyObject set_default_proc20(IRubyObject proc) {
}

IRubyObject b = TypeConverter.convertToType(proc, getRuntime().getProc(), "to_proc");
if(b.isNil() || !(b instanceof RubyProc)) {
if (b.isNil() || !(b instanceof RubyProc)) {
throw getRuntime().newTypeError("wrong default_proc type " + proc.getMetaClass() + " (expected Proc)");
}
proc = b;
@@ -780,6 +777,11 @@ public IRubyObject set_default_proc20(IRubyObject proc) {
return proc;
}

@Deprecated
public IRubyObject set_default_proc20(IRubyObject proc) {
return set_default_proc(proc);
}

/** rb_hash_modify
*
*/
@@ -802,28 +804,42 @@ private IRubyObject inspectHash(final ThreadContext context) {
private static final VisitorWithState<RubyString> InspectVisitor = new VisitorWithState<RubyString>() {
@Override
public void visit(ThreadContext context, RubyHash self, IRubyObject key, IRubyObject value, int index, RubyString str) {
if (index > 0) str.cat((byte)',').cat((byte)' ');
RubyString keyStr = inspect(context, key);
RubyString valStr = inspect(context, value);

str.cat19(inspect(context, key)).cat((byte)'=').cat((byte)'>').cat19(inspect(context, value));
final ByteList bytes = str.getByteList();
bytes.ensure(2 + keyStr.size() + 2 + valStr.size());

if (index > 0) bytes.append((byte) ',').append((byte) ' ');

str.cat19(keyStr);
bytes.append((byte) '=').append((byte) '>');
str.cat19(valStr);
}
};

@Override
public IRubyObject inspect() {
return inspect(getRuntime().getCurrentContext());
}

/** rb_hash_inspect
*
*/
@JRubyMethod(name = "inspect")
public IRubyObject inspect(ThreadContext context) {
if (size == 0) return RubyString.newUSASCIIString(context.runtime, "{}");
if (getRuntime().isInspecting(this)) return RubyString.newUSASCIIString(context.runtime, "{...}");
if (context.runtime.isInspecting(this)) return RubyString.newUSASCIIString(context.runtime, "{...}");

try {
getRuntime().registerInspecting(this);
context.runtime.registerInspecting(this);
return inspectHash(context);
} finally {
getRuntime().unregisterInspecting(this);
context.runtime.unregisterInspecting(this);
}
}

@Deprecated
public IRubyObject inspect19(ThreadContext context) {
return inspect(context);
}
@@ -1145,15 +1161,18 @@ public IRubyObject op_ge(ThreadContext context, IRubyObject other) {
*
*/
@Override
@JRubyMethod(name = "hash")
public RubyFixnum hash() {
Ruby runtime = getRuntime();
ThreadContext context = runtime.getCurrentContext();
long[] hval = {Helpers.hashStart(runtime, size())};
return hash(getRuntime().getCurrentContext());
}

@JRubyMethod(name = "hash")
public RubyFixnum hash(ThreadContext context) {
final int size = size();
long[] hval = { Helpers.hashStart(context.runtime, size) };
if (size > 0) {
iteratorVisitAll(context, CalculateHashVisitor, hval);
}
return runtime.newFixnum(hval[0]);
return context.runtime.newFixnum(hval[0]);
}

private static final VisitorWithState<long[]> CalculateHashVisitor = new VisitorWithState<long[]>() {
@@ -1165,8 +1184,8 @@ public void visit(ThreadContext context, RubyHash self, IRubyObject key, IRubyOb
};

@Deprecated
public RubyFixnum hash19() {
return hash();
public final RubyFixnum hash19() {
return hash(getRuntime().getCurrentContext());
}

/** rb_hash_fetch
@@ -1279,7 +1298,7 @@ public void visit(ThreadContext context, RubyHash self, IRubyObject key, IRubyOb
*/
@JRubyMethod(name = {"has_value?", "value?"}, required = 1)
public RubyBoolean has_value_p(ThreadContext context, IRubyObject expected) {
return getRuntime().newBoolean(hasValue(context, expected));
return context.runtime.newBoolean(hasValue(context, expected));
}

private volatile int iteratorCount;
@@ -1485,6 +1504,7 @@ public IRubyObject index(ThreadContext context, IRubyObject expected) {
return key(context, expected);
}

@Deprecated
public IRubyObject index19(ThreadContext context, IRubyObject expected) {
return index(context, expected);
}
@@ -1636,8 +1656,9 @@ public void visit(ThreadContext context, RubyHash self, IRubyObject key, IRubyOb
result.fastASet(key, value);
}
}
};
}

@Deprecated
public IRubyObject select19(ThreadContext context, Block block) {
return select(context, block);
}
Original file line number Diff line number Diff line change
@@ -139,15 +139,15 @@ protected IRubyObject inspectAry(ThreadContext context) {

final Ruby runtime = context.runtime;
RubyString str = RubyString.newStringLight(runtime, DEFAULT_INSPECT_STR_SIZE, USASCIIEncoding.INSTANCE);
EncodingUtils.strBufCat(runtime, str, OPEN_BRACKET);
str.cat((byte) '[');
boolean tainted = isTaint();

RubyString s = inspect(context, value);
if (s.isTaint()) tainted = true;
else str.setEncoding(s.getEncoding());
str.cat19(s);

EncodingUtils.strBufCat(runtime, str, CLOSE_BRACKET);
str.cat((byte) ']');

if (tainted) str.setTaint(true);

Original file line number Diff line number Diff line change
@@ -13,6 +13,7 @@
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.runtime.invokedynamic.MethodNames;
import org.jruby.util.ByteList;
import org.jruby.util.io.EncodingUtils;

import static org.jruby.RubyEnumerator.enumeratorizeWithSize;
@@ -152,7 +153,7 @@ protected IRubyObject inspectAry(ThreadContext context) {

final Ruby runtime = context.runtime;
RubyString str = RubyString.newStringLight(runtime, DEFAULT_INSPECT_STR_SIZE, USASCIIEncoding.INSTANCE);
EncodingUtils.strBufCat(runtime, str, OPEN_BRACKET);
str.cat((byte) '[');
boolean tainted = isTaint();

RubyString s1 = inspect(context, car);
@@ -161,13 +162,15 @@ protected IRubyObject inspectAry(ThreadContext context) {
else str.setEncoding(s1.getEncoding());
str.cat19(s1);

EncodingUtils.strBufCat(runtime, str, COMMA_SPACE);
ByteList bytes = str.getByteList();
bytes.ensure(2 + s2.size() + 1);
bytes.append((byte) ',').append((byte) ' ');

if (s2.isTaint()) tainted = true;
else str.setEncoding(s2.getEncoding());
str.cat19(s2);

EncodingUtils.strBufCat(runtime, str, CLOSE_BRACKET);
str.cat((byte) ']');

if (tainted) str.setTaint(true);