Skip to content

Commit f94a818

Browse files
committed
Improve StringIO performance
1 parent ad00b91 commit f94a818

File tree

2 files changed

+109
-57
lines changed

2 files changed

+109
-57
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/PStringIO.java

Lines changed: 45 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -40,9 +40,13 @@
4040
*/
4141
package com.oracle.graal.python.builtins.modules.io;
4242

43-
import static com.oracle.graal.python.nodes.StringLiterals.T_EMPTY_STRING;
4443
import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING;
4544

45+
import com.oracle.truffle.api.dsl.Cached;
46+
import com.oracle.truffle.api.dsl.GenerateCached;
47+
import com.oracle.truffle.api.dsl.GenerateInline;
48+
import com.oracle.truffle.api.dsl.Specialization;
49+
import com.oracle.truffle.api.nodes.Node;
4650
import com.oracle.truffle.api.object.Shape;
4751
import com.oracle.truffle.api.strings.TruffleString;
4852
import com.oracle.truffle.api.strings.TruffleStringBuilder;
@@ -58,24 +62,28 @@ public final class PStringIO extends PTextIOBase {
5862

5963
private boolean closed;
6064

61-
private TruffleString buf;
65+
private TruffleString cachedString;
66+
private TruffleStringBuilder buf;
6267
private TruffleStringBuilder sb;
6368
private int pos;
6469
private int stringSize;
6570

6671
public PStringIO(Object cls, Shape instanceShape) {
6772
super(cls, instanceShape);
68-
buf = T_EMPTY_STRING;
73+
buf = null;
6974
}
7075

71-
public TruffleString getBuf() {
72-
assert !isAccumulating();
76+
public TruffleStringBuilder getBuf() {
7377
return buf;
7478
}
7579

76-
public void setBuf(TruffleString buf) {
77-
assert !isAccumulating();
80+
public void setBuf(TruffleStringBuilder buf) {
7881
this.buf = buf;
82+
cachedString = null;
83+
}
84+
85+
public void invalidateBufCache() {
86+
cachedString = null;
7987
}
8088

8189
public int getPos() {
@@ -106,11 +114,12 @@ public boolean isClosed() {
106114
return closed;
107115
}
108116

109-
public void realize(TruffleStringBuilder.ToStringNode toStringNode) {
117+
public void realize() {
110118
if (!isAccumulating()) {
111119
return;
112120
}
113-
buf = toStringNode.execute(sb);
121+
buf = sb;
122+
cachedString = null;
114123
sb = null;
115124
}
116125

@@ -121,6 +130,7 @@ public boolean isAccumulating() {
121130
public void setAccumulating() {
122131
assert stringSize == 0 && !isAccumulating();
123132
sb = TruffleStringBuilder.create(TS_ENCODING);
133+
cachedString = null;
124134
}
125135

126136
public void append(TruffleString str, TruffleStringBuilder.AppendStringNode appendStringNode) {
@@ -130,7 +140,7 @@ public void append(TruffleString str, TruffleStringBuilder.AppendStringNode appe
130140

131141
public void setRealized() {
132142
sb = null;
133-
buf = T_EMPTY_STRING;
143+
buf = TruffleStringBuilder.create(TS_ENCODING);
134144
}
135145

136146
public TruffleString makeIntermediate(TruffleStringBuilder.ToStringNode toStringNode) {
@@ -141,8 +151,31 @@ public TruffleString makeIntermediate(TruffleStringBuilder.ToStringNode toString
141151
@Override
142152
public void clearAll() {
143153
super.clearAll();
144-
buf = T_EMPTY_STRING;
154+
buf = TruffleStringBuilder.create(TS_ENCODING);
145155
sb = null;
156+
cachedString = null;
146157
setWriteNewline(null);
147158
}
159+
160+
@GenerateInline
161+
@GenerateCached(false)
162+
abstract static class PStringIOBufToStringNode extends Node {
163+
abstract TruffleString execute(Node inliningTarget, PStringIO self);
164+
165+
static boolean hasCache(PStringIO s) {
166+
return s.cachedString != null;
167+
}
168+
169+
@Specialization(guards = "hasCache(self)")
170+
TruffleString doCached(PStringIO self) {
171+
return self.cachedString;
172+
}
173+
174+
@Specialization(guards = "!hasCache(self)")
175+
TruffleString doUncached(PStringIO self,
176+
@Cached(inline = false) TruffleStringBuilder.ToStringNode toStringNode) {
177+
self.cachedString = toStringNode.execute(self.getBuf());
178+
return self.cachedString;
179+
}
180+
}
148181
}

0 commit comments

Comments
 (0)