Skip to content

Commit 1add124

Browse files
authored
Merge pull request stleary#348 from johnjaylward/ArrayPerformance
Capacity improvements for internal structures
2 parents 5b2e5e7 + 2fbe4d9 commit 1add124

File tree

3 files changed

+31
-9
lines changed

3 files changed

+31
-9
lines changed

JSONArray.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,10 @@ public JSONArray(String source) throws JSONException {
154154
* A Collection.
155155
*/
156156
public JSONArray(Collection<?> collection) {
157-
this.myArrayList = new ArrayList<Object>();
158-
if (collection != null) {
157+
if (collection == null) {
158+
this.myArrayList = new ArrayList<Object>();
159+
} else {
160+
this.myArrayList = new ArrayList<Object>(collection.size());
159161
for (Object o: collection){
160162
this.myArrayList.add(JSONObject.wrap(o));
161163
}
@@ -172,6 +174,7 @@ public JSONArray(Object array) throws JSONException {
172174
this();
173175
if (array.getClass().isArray()) {
174176
int length = Array.getLength(array);
177+
this.myArrayList.ensureCapacity(length);
175178
for (int i = 0; i < length; i += 1) {
176179
this.put(JSONObject.wrap(Array.get(array, i)));
177180
}
@@ -495,7 +498,7 @@ public int length() {
495498
* Get the optional object value associated with an index.
496499
*
497500
* @param index
498-
* The index must be between 0 and length() - 1.
501+
* The index must be between 0 and length() - 1. If not, null is returned.
499502
* @return An object value, or null if there is no object at that index.
500503
*/
501504
public Object opt(int index) {
@@ -1150,7 +1153,13 @@ public JSONArray put(int index, Object value) throws JSONException {
11501153
}
11511154
if (index < this.length()) {
11521155
this.myArrayList.set(index, value);
1156+
} else if(index == this.length()){
1157+
// simple append
1158+
this.put(value);
11531159
} else {
1160+
// if we are inserting past the length, we want to grow the array all at once
1161+
// instead of incrementally.
1162+
this.myArrayList.ensureCapacity(index + 1);
11541163
while (index != this.length()) {
11551164
this.put(JSONObject.NULL);
11561165
}
@@ -1302,7 +1311,7 @@ public JSONObject toJSONObject(JSONArray names) throws JSONException {
13021311
if (names == null || names.length() == 0 || this.length() == 0) {
13031312
return null;
13041313
}
1305-
JSONObject jo = new JSONObject();
1314+
JSONObject jo = new JSONObject(names.length());
13061315
for (int i = 0; i < names.length(); i += 1) {
13071316
jo.put(names.getString(i), this.opt(i));
13081317
}

JSONObject.java

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ public JSONObject() {
184184
* An array of strings.
185185
*/
186186
public JSONObject(JSONObject jo, String[] names) {
187-
this();
187+
this(names.length);
188188
for (int i = 0; i < names.length; i += 1) {
189189
try {
190190
this.putOnce(names[i], jo.opt(names[i]));
@@ -256,8 +256,10 @@ public JSONObject(JSONTokener x) throws JSONException {
256256
* the JSONObject.
257257
*/
258258
public JSONObject(Map<?, ?> m) {
259-
this.map = new HashMap<String, Object>();
260-
if (m != null) {
259+
if (m == null) {
260+
this.map = new HashMap<String, Object>();
261+
} else {
262+
this.map = new HashMap<String, Object>(m.size());
261263
for (final Entry<?, ?> e : m.entrySet()) {
262264
final Object value = e.getValue();
263265
if (value != null) {
@@ -308,7 +310,7 @@ public JSONObject(Object bean) {
308310
* from the object.
309311
*/
310312
public JSONObject(Object object, String names[]) {
311-
this();
313+
this(names.length);
312314
Class<?> c = object.getClass();
313315
for (int i = 0; i < names.length; i += 1) {
314316
String name = names[i];
@@ -377,6 +379,17 @@ public JSONObject(String baseName, Locale locale) throws JSONException {
377379
}
378380
}
379381
}
382+
383+
/**
384+
* Constructor to specify an initial capacity of the internal map. Useful for library
385+
* internal calls where we know, or at least can best guess, how big this JSONObject
386+
* will be.
387+
*
388+
* @param initialCapacity initial capacity of the internal map.
389+
*/
390+
protected JSONObject(int initialCapacity){
391+
this.map = new HashMap<String, Object>(initialCapacity);
392+
}
380393

381394
/**
382395
* Accumulate values under a key. It is similar to the put method except

Property.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public class Property {
4141
* @throws JSONException
4242
*/
4343
public static JSONObject toJSONObject(java.util.Properties properties) throws JSONException {
44-
JSONObject jo = new JSONObject();
44+
JSONObject jo = new JSONObject(properties == null ? 0 : properties.size());
4545
if (properties != null && !properties.isEmpty()) {
4646
Enumeration<?> enumProperties = properties.propertyNames();
4747
while(enumProperties.hasMoreElements()) {

0 commit comments

Comments
 (0)