Skip to content

Commit bb39f59

Browse files
committed
Optimize sequence fills like '[0] * n'.
1 parent a1eaac4 commit bb39f59

File tree

1 file changed

+106
-1
lines changed

1 file changed

+106
-1
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/SequenceStorageNodes.java

Lines changed: 106 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2395,10 +2395,115 @@ SequenceStorage doEmpty(EmptySequenceStorage s, @SuppressWarnings("unused") int
23952395

23962396
@Specialization(guards = "times <= 0")
23972397
SequenceStorage doZeroRepeat(SequenceStorage s, @SuppressWarnings("unused") int times,
2398-
@Cached("create()") CreateEmptyNode createEmptyNode) {
2398+
@Cached CreateEmptyNode createEmptyNode) {
23992399
return createEmptyNode.execute(s, 0);
24002400
}
24012401

2402+
/* special but common case: something like '[False] * n' */
2403+
@Specialization(guards = {"s.length() == 1", "times > 0"})
2404+
BoolSequenceStorage doBoolSingleElement(BoolSequenceStorage s, int times,
2405+
@Shared("raiseNode") @Cached PRaiseNode raiseNode,
2406+
@Cached BranchProfile outOfMemProfile) {
2407+
try {
2408+
boolean[] repeated = new boolean[Math.multiplyExact(s.length(), times)];
2409+
Arrays.fill(repeated, s.getBoolItemNormalized(0));
2410+
return new BoolSequenceStorage(repeated);
2411+
} catch (OutOfMemoryError | ArithmeticException e) {
2412+
outOfMemProfile.enter();
2413+
throw raiseNode.raise(MemoryError);
2414+
}
2415+
}
2416+
2417+
/* special but common case: something like '["\x00"] * n' */
2418+
@Specialization(guards = {"s.length() == 1", "times > 0"})
2419+
ByteSequenceStorage doByteSingleElement(ByteSequenceStorage s, int times,
2420+
@Shared("raiseNode") @Cached PRaiseNode raiseNode,
2421+
@Cached BranchProfile outOfMemProfile) {
2422+
try {
2423+
byte[] repeated = new byte[Math.multiplyExact(s.length(), times)];
2424+
Arrays.fill(repeated, s.getByteItemNormalized(0));
2425+
return new ByteSequenceStorage(repeated);
2426+
} catch (OutOfMemoryError | ArithmeticException e) {
2427+
outOfMemProfile.enter();
2428+
throw raiseNode.raise(MemoryError);
2429+
}
2430+
}
2431+
2432+
/* special but common case: something like '["0"] * n' */
2433+
@Specialization(guards = {"s.length() == 1", "times > 0"})
2434+
CharSequenceStorage doCharSingleElement(CharSequenceStorage s, int times,
2435+
@Shared("raiseNode") @Cached PRaiseNode raiseNode,
2436+
@Cached BranchProfile outOfMemProfile) {
2437+
try {
2438+
char[] repeated = new char[Math.multiplyExact(s.length(), times)];
2439+
Arrays.fill(repeated, s.getCharItemNormalized(0));
2440+
return new CharSequenceStorage(repeated);
2441+
} catch (OutOfMemoryError | ArithmeticException e) {
2442+
outOfMemProfile.enter();
2443+
throw raiseNode.raise(MemoryError);
2444+
}
2445+
}
2446+
2447+
/* special but common case: something like '[0] * n' */
2448+
@Specialization(guards = {"s.length() == 1", "times > 0"})
2449+
IntSequenceStorage doIntSingleElement(IntSequenceStorage s, int times,
2450+
@Shared("raiseNode") @Cached PRaiseNode raiseNode,
2451+
@Cached BranchProfile outOfMemProfile) {
2452+
try {
2453+
int[] repeated = new int[Math.multiplyExact(s.length(), times)];
2454+
Arrays.fill(repeated, s.getIntItemNormalized(0));
2455+
return new IntSequenceStorage(repeated);
2456+
} catch (OutOfMemoryError | ArithmeticException e) {
2457+
outOfMemProfile.enter();
2458+
throw raiseNode.raise(MemoryError);
2459+
}
2460+
}
2461+
2462+
/* special but common case: something like '[0L] * n' */
2463+
@Specialization(guards = {"s.length() == 1", "times > 0"})
2464+
LongSequenceStorage doLongSingleElement(LongSequenceStorage s, int times,
2465+
@Shared("raiseNode") @Cached PRaiseNode raiseNode,
2466+
@Cached BranchProfile outOfMemProfile) {
2467+
try {
2468+
long[] repeated = new long[Math.multiplyExact(s.length(), times)];
2469+
Arrays.fill(repeated, s.getLongItemNormalized(0));
2470+
return new LongSequenceStorage(repeated);
2471+
} catch (OutOfMemoryError | ArithmeticException e) {
2472+
outOfMemProfile.enter();
2473+
throw raiseNode.raise(MemoryError);
2474+
}
2475+
}
2476+
2477+
/* special but common case: something like '[0.0] * n' */
2478+
@Specialization(guards = {"s.length() == 1", "times > 0"})
2479+
DoubleSequenceStorage doDoubleSingleElement(DoubleSequenceStorage s, int times,
2480+
@Shared("raiseNode") @Cached PRaiseNode raiseNode,
2481+
@Cached BranchProfile outOfMemProfile) {
2482+
try {
2483+
double[] repeated = new double[Math.multiplyExact(s.length(), times)];
2484+
Arrays.fill(repeated, s.getDoubleItemNormalized(0));
2485+
return new DoubleSequenceStorage(repeated);
2486+
} catch (OutOfMemoryError | ArithmeticException e) {
2487+
outOfMemProfile.enter();
2488+
throw raiseNode.raise(MemoryError);
2489+
}
2490+
}
2491+
2492+
/* special but common case: something like '[None] * n' */
2493+
@Specialization(guards = {"s.length() == 1", "times > 0"})
2494+
ObjectSequenceStorage doObjectSingleElement(ObjectSequenceStorage s, int times,
2495+
@Shared("raiseNode") @Cached PRaiseNode raiseNode,
2496+
@Cached BranchProfile outOfMemProfile) {
2497+
try {
2498+
Object[] repeated = new Object[Math.multiplyExact(s.length(), times)];
2499+
Arrays.fill(repeated, s.getItemNormalized(0));
2500+
return new ObjectSequenceStorage(repeated);
2501+
} catch (OutOfMemoryError | ArithmeticException e) {
2502+
outOfMemProfile.enter();
2503+
throw raiseNode.raise(MemoryError);
2504+
}
2505+
}
2506+
24022507
@Specialization(limit = "MAX_ARRAY_STORAGES", guards = {"times > 0", "!isNative(s)", "s.getClass() == cachedClass"})
24032508
SequenceStorage doManaged(BasicSequenceStorage s, int times,
24042509
@Exclusive @Cached PRaiseNode raiseNode,

0 commit comments

Comments
 (0)