Skip to content

Commit 51cd6a2

Browse files
MINOR: Dry up RubyArray and improve performance in a few spots
1 parent 2e6f9d9 commit 51cd6a2

File tree

3 files changed

+74
-88
lines changed

3 files changed

+74
-88
lines changed

core/src/main/java/org/jruby/RubyArray.java

Lines changed: 74 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,18 @@
3737
***** END LICENSE BLOCK *****/
3838
package org.jruby;
3939

40+
import java.io.IOException;
41+
import java.lang.reflect.Array;
42+
import java.math.BigInteger;
43+
import java.util.ArrayList;
44+
import java.util.Arrays;
45+
import java.util.Collection;
46+
import java.util.Comparator;
47+
import java.util.IdentityHashMap;
48+
import java.util.Iterator;
49+
import java.util.List;
50+
import java.util.ListIterator;
51+
import java.util.RandomAccess;
4052
import org.jcodings.specific.USASCIIEncoding;
4153
import org.jruby.anno.JRubyClass;
4254
import org.jruby.anno.JRubyMethod;
@@ -69,26 +81,13 @@
6981
import org.jruby.util.TypeConverter;
7082
import org.jruby.util.cli.Options;
7183

72-
import java.io.IOException;
73-
import java.lang.reflect.Array;
74-
import java.math.BigInteger;
75-
import java.util.ArrayList;
76-
import java.util.Arrays;
77-
import java.util.Collection;
78-
import java.util.Comparator;
79-
import java.util.IdentityHashMap;
80-
import java.util.Iterator;
81-
import java.util.List;
82-
import java.util.ListIterator;
83-
import java.util.RandomAccess;
84-
84+
import static org.jruby.RubyEnumerator.SizeFn;
8585
import static org.jruby.RubyEnumerator.enumeratorize;
8686
import static org.jruby.RubyEnumerator.enumeratorizeWithSize;
8787
import static org.jruby.runtime.Helpers.arrayOf;
8888
import static org.jruby.runtime.Helpers.hashEnd;
8989
import static org.jruby.runtime.Helpers.murmurCombine;
9090
import static org.jruby.runtime.Visibility.PRIVATE;
91-
import static org.jruby.RubyEnumerator.SizeFn;
9291

9392
/**
9493
* The implementation of the built-in class Array in Ruby.
@@ -246,37 +245,59 @@ public static RubyArray newEmptyArray(Ruby runtime) {
246245
*
247246
*/
248247
public static RubyArray newArray(Ruby runtime, IRubyObject[] args) {
249-
switch (args.length) {
250-
case 0:
251-
return newEmptyArray(runtime);
252-
case 1:
253-
if (USE_PACKED_ARRAYS) return new RubyArrayOneObject(runtime, args[0]);
254-
break;
255-
case 2:
256-
if (USE_PACKED_ARRAYS) return new RubyArrayTwoObject(runtime, args[0], args[1]);
257-
break;
248+
final int size = args.length;
249+
if (size == 0) {
250+
return newEmptyArray(runtime);
258251
}
259-
RubyArray arr = new RubyArray(runtime, new IRubyObject[args.length]);
260-
System.arraycopy(args, 0, arr.values, 0, args.length);
261-
arr.realLength = args.length;
262-
return arr;
252+
return isPackedArray(size) ? packedArray(runtime, args)
253+
: new RubyArray(runtime, args.clone());
254+
}
255+
256+
public static RubyArray newArray(Ruby runtime, Collection<? extends IRubyObject> collection) {
257+
if (collection.isEmpty()) {
258+
return newEmptyArray(runtime);
259+
}
260+
final IRubyObject[] arr = collection.toArray(IRubyObject.NULL_ARRAY);
261+
return isPackedArray(collection) ? packedArray(runtime, arr) : new RubyArray(runtime, arr);
263262
}
264263

264+
public static RubyArray newArray(Ruby runtime, List<? extends IRubyObject> list) {
265+
if (list.isEmpty()) {
266+
return newEmptyArray(runtime);
267+
}
268+
return isPackedArray(list) ? packedArray(runtime, list)
269+
: new RubyArray(runtime, list.toArray(IRubyObject.NULL_ARRAY));
270+
}
271+
272+
private static RubyArray packedArray(final Ruby runtime, final IRubyObject[] args) {
273+
if (args.length == 1) {
274+
return new RubyArrayOneObject(runtime, args[0]);
275+
} else {
276+
return new RubyArrayTwoObject(runtime, args[0], args[1]);
277+
}
278+
}
279+
280+
private static RubyArray packedArray(final Ruby runtime, final List<? extends IRubyObject> args) {
281+
if (args.size() == 1) {
282+
return new RubyArrayOneObject(runtime, args.get(0));
283+
} else {
284+
return new RubyArrayTwoObject(runtime, args.get(0), args.get(1));
285+
}
286+
}
287+
288+
private static boolean isPackedArray(final int size) {
289+
return USE_PACKED_ARRAYS && size <= 2;
290+
}
291+
292+
private static boolean isPackedArray(final Collection<? extends IRubyObject> collection) {
293+
return USE_PACKED_ARRAYS && collection.size() <= 2;
294+
}
295+
265296
/**
266297
* @see RubyArray#newArrayMayCopy(Ruby, IRubyObject[], int, int)
267298
*/
268299
public static RubyArray newArrayMayCopy(Ruby runtime, IRubyObject... args) {
269-
switch (args.length) {
270-
case 0:
271-
return newEmptyArray(runtime);
272-
case 1:
273-
if (USE_PACKED_ARRAYS) return new RubyArrayOneObject(runtime, args[0]);
274-
break;
275-
case 2:
276-
if (USE_PACKED_ARRAYS) return new RubyArrayTwoObject(runtime, args[0], args[1]);
277-
break;
278-
}
279-
return newArrayNoCopy(runtime, args, 0, args.length);
300+
return newArrayMayCopy(runtime, args, 0, args.length);
280301
}
281302

282303
/**
@@ -299,15 +320,16 @@ public static RubyArray newArrayMayCopy(Ruby runtime, IRubyObject[] args, int st
299320
* @return an array referencing the given elements
300321
*/
301322
public static RubyArray newArrayMayCopy(Ruby runtime, IRubyObject[] args, int start, int length) {
302-
switch (length) {
303-
case 0:
304-
return newEmptyArray(runtime);
305-
case 1:
306-
if (USE_PACKED_ARRAYS) return new RubyArrayOneObject(runtime, args[start]);
307-
break;
308-
case 2:
309-
if (USE_PACKED_ARRAYS) return new RubyArrayTwoObject(runtime, args[start], args[start + 1]);
310-
break;
323+
if (length == 0) {
324+
return newEmptyArray(runtime);
325+
}
326+
if (USE_PACKED_ARRAYS) {
327+
if (length == 1) {
328+
return new RubyArrayOneObject(runtime, args[start]);
329+
}
330+
if (length == 2) {
331+
return new RubyArrayTwoObject(runtime, args[start], args[start + 1]);
332+
}
311333
}
312334
return newArrayNoCopy(runtime, args, start, length);
313335
}
@@ -334,35 +356,6 @@ public static RubyArray newArrayNoCopyLight(Ruby runtime, IRubyObject[] args) {
334356
return arr;
335357
}
336358

337-
public static RubyArray newArray(Ruby runtime, Collection<? extends IRubyObject> collection) {
338-
// This may seem inefficient for packed arrays, but the cost of this versus is not really worse
339-
// than the cost of constructing and walking an Iterator.
340-
IRubyObject[] values = collection.toArray(new IRubyObject[collection.size()]);
341-
switch (values.length) {
342-
case 0: return newEmptyArray(runtime);
343-
case 1:
344-
if (USE_PACKED_ARRAYS) return new RubyArrayOneObject(runtime, values[0]);
345-
break;
346-
case 2:
347-
if (USE_PACKED_ARRAYS) return new RubyArrayTwoObject(runtime, values[0], values[1]);
348-
break;
349-
}
350-
return new RubyArray(runtime, values);
351-
}
352-
353-
public static RubyArray newArray(Ruby runtime, List<? extends IRubyObject> list) {
354-
switch (list.size()) {
355-
case 0: return newEmptyArray(runtime);
356-
case 1:
357-
if (USE_PACKED_ARRAYS) return new RubyArrayOneObject(runtime, list.get(0));
358-
break;
359-
case 2:
360-
if (USE_PACKED_ARRAYS) return new RubyArrayTwoObject(runtime, list.get(0), list.get(1));
361-
break;
362-
}
363-
return new RubyArray(runtime, list.toArray(new IRubyObject[list.size()]));
364-
}
365-
366359
public static final int ARRAY_DEFAULT_SIZE = 16;
367360

368361
// volatile to ensure that initial nil-fill is visible to other threads
@@ -3828,7 +3821,7 @@ public IRubyObject size(IRubyObject[] args) {
38283821
};
38293822
}
38303823

3831-
private IRubyObject binomialCoefficient(ThreadContext context, long comb, long size) {
3824+
private static IRubyObject binomialCoefficient(ThreadContext context, long comb, long size) {
38323825
Ruby runtime = context.runtime;
38333826
if (comb > size - comb) {
38343827
comb = size - comb;
@@ -4029,7 +4022,7 @@ public IRubyObject size(IRubyObject[] args) {
40294022
};
40304023
}
40314024

4032-
private IRubyObject descendingFactorial(ThreadContext context, long from, long howMany) {
4025+
private static IRubyObject descendingFactorial(ThreadContext context, long from, long howMany) {
40334026
Ruby runtime = context.runtime;
40344027
IRubyObject cnt = howMany >= 0 ? RubyFixnum.one(runtime) : RubyFixnum.zero(runtime);
40354028
CallSite op_times = sites(context).op_times;
@@ -4059,7 +4052,7 @@ public IRubyObject shuffle_bang(ThreadContext context, IRubyObject[] args) {
40594052
if (args.length > 0) {
40604053
IRubyObject hash = TypeConverter.checkHashType(context.runtime, args[args.length - 1]);
40614054
if (!hash.isNil()) {
4062-
IRubyObject[] rets = ArgsUtil.extractKeywordArgs(context, (RubyHash) hash, new String[] { "random" });
4055+
IRubyObject[] rets = ArgsUtil.extractKeywordArgs(context, (RubyHash) hash, "random");
40634056
if (!rets[0].isNil()) randgen = rets[0];
40644057
}
40654058
}
@@ -4100,7 +4093,7 @@ public IRubyObject sample(ThreadContext context, IRubyObject[] args) {
41004093
if (args.length > 0) {
41014094
IRubyObject hash = TypeConverter.checkHashType(context.runtime, args[args.length - 1]);
41024095
if (!hash.isNil()) {
4103-
IRubyObject[] rets = ArgsUtil.extractKeywordArgs(context, (RubyHash) hash, new String[] { "random" });
4096+
IRubyObject[] rets = ArgsUtil.extractKeywordArgs(context, (RubyHash) hash, "random");
41044097
if (!rets[0].isNil()) randgen = rets[0];
41054098
args = ArraySupport.newCopy(args, args.length - 1);
41064099
}
@@ -4792,7 +4785,7 @@ public IRubyObject min(ThreadContext context, IRubyObject num, Block block) {
47924785
}
47934786

47944787
private static final int optimizedCmp(ThreadContext context, IRubyObject a, IRubyObject b, int token, CachingCallSite op_cmp, CallSite op_gt, CallSite op_lt) {
4795-
if (token == ((RubyBasicObject) a).getMetaClass().generation) {
4788+
if (token == a.getMetaClass().generation) {
47964789
if (a instanceof RubyFixnum && b instanceof RubyFixnum) {
47974790
long aLong = ((RubyFixnum) a).getLongValue();
47984791
long bLong = ((RubyFixnum) b).getLongValue();

core/src/main/java/org/jruby/specialized/RubyArrayOneObject.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,12 @@
44
import org.jruby.Ruby;
55
import org.jruby.RubyArray;
66
import org.jruby.RubyClass;
7-
import org.jruby.RubyFixnum;
87
import org.jruby.RubyString;
98
import org.jruby.javasupport.JavaUtil;
109
import org.jruby.runtime.Block;
11-
import org.jruby.runtime.Constants;
1210
import org.jruby.runtime.ThreadContext;
1311
import org.jruby.runtime.builtin.IRubyObject;
14-
import org.jruby.util.io.EncodingUtils;
1512

16-
import static org.jruby.RubyEnumerator.enumeratorizeWithSize;
1713
import static org.jruby.runtime.Helpers.arrayOf;
1814

1915
/**

core/src/main/java/org/jruby/specialized/RubyArrayTwoObject.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,11 @@
99
import org.jruby.RubyString;
1010
import org.jruby.javasupport.JavaUtil;
1111
import org.jruby.runtime.Block;
12-
import org.jruby.runtime.Constants;
1312
import org.jruby.runtime.ThreadContext;
1413
import org.jruby.runtime.builtin.IRubyObject;
1514
import org.jruby.runtime.invokedynamic.MethodNames;
1615
import org.jruby.util.ByteList;
17-
import org.jruby.util.io.EncodingUtils;
1816

19-
import static org.jruby.RubyEnumerator.enumeratorizeWithSize;
2017
import static org.jruby.runtime.Helpers.arrayOf;
2118
import static org.jruby.runtime.Helpers.invokedynamic;
2219

0 commit comments

Comments
 (0)