Skip to content

Commit a9cc86b

Browse files
committed
Optimizations
1 parent 79c63c6 commit a9cc86b

36 files changed

+307
-181
lines changed

releases/pyjavabridge-dev.jar

18.3 KB
Binary file not shown.

src/main/java/com/pyjavabridge/BridgeInstance.java

Lines changed: 44 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -392,11 +392,11 @@ private void handleRegisterCommand(JsonObject message) {
392392

393393
Map<Integer, List<String>> completions = null;
394394
if (message.has("completions")) {
395-
completions = new java.util.HashMap<>();
395+
completions = new java.util.HashMap<>(16);
396396
JsonObject compObj = message.getAsJsonObject("completions");
397397
for (var entry : compObj.entrySet()) {
398398
int index = Integer.parseInt(entry.getKey());
399-
List<String> values = new ArrayList<>();
399+
List<String> values = new ArrayList<>(entry.getValue().getAsJsonArray().size());
400400
for (var el : entry.getValue().getAsJsonArray()) {
401401
values.add(el.getAsString());
402402
}
@@ -415,7 +415,9 @@ private void handleTabCompleteResponse(JsonObject message) {
415415

416416
List<String> results = new ArrayList<>();
417417
if (message.has("results") && message.get("results").isJsonArray()) {
418-
for (var el : message.getAsJsonArray("results")) {
418+
var arr = message.getAsJsonArray("results");
419+
results = new ArrayList<>(arr.size());
420+
for (var el : arr) {
419421
results.add(el.getAsString());
420422
}
421423
}
@@ -477,7 +479,7 @@ private void handleRemoveEntities(JsonObject message) {
477479
if (hasId) sendError(id, "remove_entities requires handles array", null);
478480
return;
479481
}
480-
List<Integer> handles = new ArrayList<>();
482+
List<Integer> handles = new ArrayList<>(handlesEl.getAsJsonArray().size());
481483
for (JsonElement el : handlesEl.getAsJsonArray()) {
482484
handles.add(el.getAsInt());
483485
}
@@ -591,8 +593,9 @@ private void handleMoveEntities(JsonObject message) {
591593
private void handleRelease(JsonObject message) {
592594
JsonElement handlesEl = message.get("handles");
593595
if (handlesEl != null && handlesEl.isJsonArray()) {
594-
List<Integer> ids = new ArrayList<>();
595-
for (JsonElement el : handlesEl.getAsJsonArray()) {
596+
var idArray = handlesEl.getAsJsonArray();
597+
List<Integer> ids = new ArrayList<>(idArray.size());
598+
for (JsonElement el : idArray) {
596599
ids.add(el.getAsInt());
597600
}
598601
registry.releaseAll(ids);
@@ -807,10 +810,11 @@ private void handleCall(JsonObject message, long startNano) {
807810
private void handleCallBatch(JsonObject message, long startNano) {
808811

809812
boolean atomic = message.has("atomic") && message.get("atomic").getAsBoolean();
810-
List<JsonObject> calls = new ArrayList<>();
813+
var msgArray = message.has("messages") ? message.getAsJsonArray("messages") : null;
814+
List<JsonObject> calls = new ArrayList<>(msgArray != null ? msgArray.size() : 4);
811815

812-
if (message.has("messages")) {
813-
for (JsonElement element : message.getAsJsonArray("messages")) {
816+
if (msgArray != null) {
817+
for (JsonElement element : msgArray) {
814818
if (element.isJsonObject()) {
815819
calls.add(element.getAsJsonObject());
816820
}
@@ -844,8 +848,8 @@ private void handleCallBatch(JsonObject message, long startNano) {
844848

845849
private void executeBatchCalls(List<JsonObject> calls, boolean atomic, long startNano) {
846850
if (atomic) {
847-
List<JsonObject> responses = new ArrayList<>();
848-
List<Integer> ids = new ArrayList<>();
851+
List<JsonObject> responses = new ArrayList<>(calls.size());
852+
List<Integer> ids = new ArrayList<>(calls.size());
849853
boolean failed = false;
850854
int failedId = -1;
851855
Exception failedEx = null;
@@ -895,7 +899,7 @@ private void executeBatchCalls(List<JsonObject> calls, boolean atomic, long star
895899
return;
896900
}
897901

898-
List<JsonObject> batchResponses = new ArrayList<>();
902+
List<JsonObject> batchResponses = new ArrayList<>(calls.size());
899903
for (JsonObject callMessage : calls) {
900904
int id = callMessage.get("id").getAsInt();
901905

@@ -993,10 +997,11 @@ private Object invoke(JsonObject message) throws Exception {
993997

994998
JsonObject argsObj = message.has("args") ? message.getAsJsonObject("args") : EMPTY_JSON_OBJ;
995999

996-
List<Object> args = new ArrayList<>();
1000+
var argsList = message.has("args_list") ? message.getAsJsonArray("args_list") : null;
1001+
List<Object> args = new ArrayList<>(argsList != null ? argsList.size() : 4);
9971002

998-
if (message.has("args_list")) {
999-
for (JsonElement element : message.getAsJsonArray("args_list")) {
1003+
if (argsList != null) {
1004+
for (JsonElement element : argsList) {
10001005
args.add(serializer.deserialize(element));
10011006
}
10021007
}
@@ -1113,7 +1118,7 @@ private List<Object> preprocessTeleportArgs(Entity entity, List<Object> args) {
11131118
private Map<String, Object> serializeMerchantRecipe(org.bukkit.inventory.MerchantRecipe recipe) {
11141119
Map<String, Object> map = new java.util.LinkedHashMap<>();
11151120
map.put("result", recipe.getResult().serialize());
1116-
List<Map<String, Object>> ingredients = new ArrayList<>();
1121+
List<Map<String, Object>> ingredients = new ArrayList<>(recipe.getIngredients().size());
11171122
for (ItemStack ingredient : recipe.getIngredients()) {
11181123
ingredients.add(ingredient.serialize());
11191124
}
@@ -1153,7 +1158,7 @@ private org.bukkit.inventory.MerchantRecipe deserializeMerchantRecipe(Map<String
11531158
// Deserialize ingredients
11541159
Object ingredientsObj = map.get("ingredients");
11551160
if (ingredientsObj instanceof List<?> ingredientsList) {
1156-
List<ItemStack> ingredients = new ArrayList<>();
1161+
List<ItemStack> ingredients = new ArrayList<>(ingredientsList.size());
11571162
for (Object ingObj : ingredientsList) {
11581163
if (ingObj instanceof Map<?, ?> ingMap) {
11591164
ItemStack ing = ItemStack.deserialize(toStringKeyMap(ingMap));
@@ -1312,7 +1317,7 @@ private Object invokeWorldMethod(World world, String method, List<Object> args,
13121317
return world.getChunkAtAsync(cx, cz);
13131318
}
13141319
if ("batchSpawn".equals(method) && !args.isEmpty() && args.get(0) instanceof List<?> batch) {
1315-
List<Entity> spawned = new ArrayList<>();
1320+
List<Entity> spawned = new ArrayList<>(batch.size());
13161321
for (Object entry : batch) {
13171322
if (entry instanceof Map<?, ?> spec) {
13181323
Object locObj = spec.get("location");
@@ -1379,7 +1384,7 @@ private Object invokeBlockMethod(Block block, String method) {
13791384
BlockState state = block.getState();
13801385
if (state instanceof Sign sign) {
13811386
SignSide side = sign.getSide(Side.FRONT);
1382-
List<String> lines = new ArrayList<>();
1387+
List<String> lines = new ArrayList<>(4);
13831388
for (int i = 0; i < 4; i++) {
13841389
lines.add(PlainTextComponentSerializer.plainText().serialize(side.line(i)));
13851390
}
@@ -1391,7 +1396,7 @@ private Object invokeBlockMethod(Block block, String method) {
13911396
BlockState state = block.getState();
13921397
if (state instanceof Sign sign) {
13931398
SignSide side = sign.getSide(Side.BACK);
1394-
List<String> lines = new ArrayList<>();
1399+
List<String> lines = new ArrayList<>(4);
13951400
for (int i = 0; i < 4; i++) {
13961401
lines.add(PlainTextComponentSerializer.plainText().serialize(side.line(i)));
13971402
}
@@ -1525,9 +1530,9 @@ private Object invokeBlockMethodWithArgs(Block block, String method, List<Object
15251530
}
15261531
if ("getDrops".equals(method)) {
15271532
if (!args.isEmpty() && args.get(0) instanceof ItemStack tool) {
1528-
return new ArrayList<>(block.getDrops(tool));
1533+
return List.copyOf(block.getDrops(tool));
15291534
}
1530-
return new ArrayList<>(block.getDrops());
1535+
return List.copyOf(block.getDrops());
15311536
}
15321537
if ("getHardness".equals(method)) {
15331538
return block.getType().getHardness();
@@ -1924,7 +1929,7 @@ private Object invokeMobMethod(Entity entity, String method, List<Object> args)
19241929
case "getGoalTypes" -> {
19251930
com.destroystokyo.paper.entity.ai.MobGoals goals = Bukkit.getMobGoals();
19261931
var allGoals = goals.getAllGoals(mob);
1927-
List<String> names = new ArrayList<>();
1932+
List<String> names = new ArrayList<>(allGoals.size());
19281933
for (var goal : allGoals) {
19291934
names.add(goal.getKey().getNamespacedKey().getKey());
19301935
}
@@ -1953,7 +1958,7 @@ private Object invokeMobMethod(Entity entity, String method, List<Object> args)
19531958
case "getRecipes" -> {
19541959
if (!(mob instanceof org.bukkit.entity.AbstractVillager villager)) return UNHANDLED;
19551960
List<org.bukkit.inventory.MerchantRecipe> recipes = villager.getRecipes();
1956-
List<Map<String, Object>> result = new ArrayList<>();
1961+
List<Map<String, Object>> result = new ArrayList<>(recipes.size());
19571962
for (org.bukkit.inventory.MerchantRecipe recipe : recipes) {
19581963
result.add(serializeMerchantRecipe(recipe));
19591964
}
@@ -1968,7 +1973,7 @@ private Object invokeMobMethod(Entity entity, String method, List<Object> args)
19681973
if (args.isEmpty()) return null;
19691974
@SuppressWarnings("unchecked")
19701975
List<Map<String, Object>> recipeMaps = (List<Map<String, Object>>) args.get(0);
1971-
List<org.bukkit.inventory.MerchantRecipe> recipes = new ArrayList<>();
1976+
List<org.bukkit.inventory.MerchantRecipe> recipes = new ArrayList<>(recipeMaps.size());
19721977
for (Map<String, Object> map : recipeMaps) {
19731978
org.bukkit.inventory.MerchantRecipe recipe = deserializeMerchantRecipe(map);
19741979
if (recipe != null) recipes.add(recipe);
@@ -1991,7 +1996,7 @@ private Object invokeMobMethod(Entity entity, String method, List<Object> args)
19911996
}
19921997
case "clearRecipes" -> {
19931998
if (!(mob instanceof org.bukkit.entity.AbstractVillager villager)) return UNHANDLED;
1994-
villager.setRecipes(new ArrayList<>());
1999+
villager.setRecipes(List.of());
19952000
return null;
19962001
}
19972002
}
@@ -2020,7 +2025,7 @@ private Object invokeItemStackMethod(ItemStack itemStack, String method, List<Ob
20202025
if (lore == null) {
20212026
return List.of();
20222027
}
2023-
List<String> loreText = new ArrayList<>();
2028+
List<String> loreText = new ArrayList<>(lore.size());
20242029
for (Component component : lore) {
20252030
loreText.add(PlainTextComponentSerializer.plainText().serialize(component));
20262031
}
@@ -2031,13 +2036,16 @@ private Object invokeItemStackMethod(ItemStack itemStack, String method, List<Ob
20312036
case "setLore" -> {
20322037
if (meta != null && !args.isEmpty()) {
20332038
Object loreArg = args.get(0);
2034-
List<Component> loreComponents = new ArrayList<>();
2039+
List<Component> loreComponents;
20352040
if (loreArg instanceof List<?> loreList) {
2041+
loreComponents = new ArrayList<>(loreList.size());
20362042
for (Object entry : loreList) {
20372043
if (entry != null) {
20382044
loreComponents.add(Component.text(entry.toString()));
20392045
}
20402046
}
2047+
} else {
2048+
loreComponents = List.of();
20412049
}
20422050
meta.lore(loreComponents);
20432051
itemStack.setItemMeta(meta);
@@ -2134,8 +2142,9 @@ private Object invokeItemStackMethod(ItemStack itemStack, String method, List<Ob
21342142
}
21352143
case "getItemFlags" -> {
21362144
if (meta != null) {
2137-
List<String> flags = new ArrayList<>();
2138-
for (ItemFlag f : meta.getItemFlags()) {
2145+
var itemFlags = meta.getItemFlags();
2146+
List<String> flags = new ArrayList<>(itemFlags.size());
2147+
for (ItemFlag f : itemFlags) {
21392148
flags.add(f.name());
21402149
}
21412150
return flags;
@@ -2202,7 +2211,7 @@ private Object invokeServerMethod(org.bukkit.Server server, String method, List<
22022211
return Bukkit.removeRecipe(new NamespacedKey(plugin, key));
22032212
}
22042213
if ("getAllEnchantments".equals(method)) {
2205-
List<String> names = new ArrayList<>();
2214+
List<String> names = new ArrayList<>(40);
22062215
Registry<org.bukkit.enchantments.Enchantment> enchReg = RegistryAccess.registryAccess().getRegistry(RegistryKey.ENCHANTMENT);
22072216
for (org.bukkit.enchantments.Enchantment ench : enchReg) {
22082217
names.add(ench.getKey().getKey().toUpperCase());
@@ -2213,7 +2222,7 @@ private Object invokeServerMethod(org.bukkit.Server server, String method, List<
22132222
String materialName = String.valueOf(args.get(0)).toUpperCase();
22142223
Material mat = Material.valueOf(materialName);
22152224
ItemStack testItem = new ItemStack(mat);
2216-
List<String> names = new ArrayList<>();
2225+
List<String> names = new ArrayList<>(16);
22172226
Registry<org.bukkit.enchantments.Enchantment> enchReg2 = RegistryAccess.registryAccess().getRegistry(RegistryKey.ENCHANTMENT);
22182227
for (org.bukkit.enchantments.Enchantment ench : enchReg2) {
22192228
if (ench.canEnchantItem(testItem)) {
@@ -2333,7 +2342,7 @@ private Object invokeServerMethod(org.bukkit.Server server, String method, List<
23332342
}
23342343
if ("listStructures".equals(method)) {
23352344
Map<NamespacedKey, org.bukkit.structure.Structure> all = Bukkit.getStructureManager().getStructures();
2336-
List<String> names = new ArrayList<>();
2345+
List<String> names = new ArrayList<>(all.size());
23372346
for (NamespacedKey k : all.keySet()) {
23382347
names.add(k.getKey());
23392348
}
@@ -2677,7 +2686,7 @@ private void setTabListHeaderFooter(Player player, String header, String footer)
26772686
}
26782687

26792688
private boolean tryTabListSetter(Player player, Object header, Object footer, Boolean headerOnly) {
2680-
List<String> methods = new ArrayList<>();
2689+
List<String> methods = new ArrayList<>(3);
26812690

26822691
if (headerOnly == null) {
26832692
methods.add("setPlayerListHeaderFooter");
@@ -2896,7 +2905,7 @@ void logError(String message, Throwable ex) {
28962905
}
28972906

28982907
private void startPythonProcess() {
2899-
List<String> command = new ArrayList<>();
2908+
List<String> command = new ArrayList<>(4);
29002909

29012910
String python = resolvePythonExecutable();
29022911

src/main/java/com/pyjavabridge/BridgeSerializer.java

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,11 @@ private JsonElement serialize(Object value, Set<Object> seen) {
136136
}
137137

138138
if (value instanceof List<?> list) {
139-
return gson.toJsonTree(list.stream().map(item -> serialize(item, seen)).toList());
139+
JsonArray arr = new JsonArray(list.size());
140+
for (Object item : list) {
141+
arr.add(serialize(item, seen));
142+
}
143+
return arr;
140144
}
141145

142146
if (value instanceof Map<?, ?> map) {
@@ -465,8 +469,9 @@ public Object deserialize(JsonElement element) {
465469
}
466470

467471
if (element.isJsonArray()) {
468-
List<Object> list = new ArrayList<>();
469-
for (JsonElement child : element.getAsJsonArray()) {
472+
var jsonArray = element.getAsJsonArray();
473+
List<Object> list = new ArrayList<>(jsonArray.size());
474+
for (JsonElement child : jsonArray) {
470475
list.add(deserialize(child));
471476
}
472477
return list;
@@ -665,9 +670,10 @@ private Object deserializeValueObject(JsonObject obj) {
665670
}
666671

667672
if (fields.has("lore") && fields.get("lore").isJsonArray()) {
668-
List<Component> lore = new ArrayList<>();
673+
var loreArr = fields.getAsJsonArray("lore");
674+
List<Component> lore = new ArrayList<>(loreArr.size());
669675

670-
for (JsonElement element : fields.getAsJsonArray("lore")) {
676+
for (JsonElement element : loreArr) {
671677
if (!element.isJsonNull()) {
672678
lore.add(Component.text(element.getAsString()));
673679
}
@@ -715,9 +721,10 @@ private Object deserializeValueObject(JsonObject obj) {
715721
}
716722

717723
if (fields.has("lore") && fields.get("lore").isJsonArray()) {
718-
List<Component> lore = new ArrayList<>();
724+
var loreArr2 = fields.getAsJsonArray("lore");
725+
List<Component> lore = new ArrayList<>(loreArr2.size());
719726

720-
for (JsonElement element : fields.getAsJsonArray("lore")) {
727+
for (JsonElement element : loreArr2) {
721728
Object loreObj = deserialize(element);
722729
if (loreObj != null) {
723730
lore.add(Component.text(loreObj.toString()));
@@ -1007,7 +1014,7 @@ public Object convertArg(Class<?> parameterType, Object arg) {
10071014
}
10081015

10091016
public Map<String, Object> deserializeArgsObject(JsonObject argsObj) {
1010-
Map<String, Object> options = new HashMap<>();
1017+
Map<String, Object> options = new HashMap<>(argsObj != null ? argsObj.size() : 4);
10111018

10121019
if (argsObj != null) {
10131020
for (Map.Entry<String, JsonElement> entry : argsObj.entrySet()) {
@@ -1130,15 +1137,15 @@ void applyAttributes(ItemMeta meta, JsonElement attributesElement) {
11301137
}
11311138

11321139
List<Map<String, Object>> attributeList(ItemMeta meta) {
1133-
List<Map<String, Object>> list = new ArrayList<>();
11341140
Multimap<Attribute, AttributeModifier> modifiers = meta.getAttributeModifiers();
11351141
if (modifiers == null) {
1136-
return list;
1142+
return List.of();
11371143
}
1144+
List<Map<String, Object>> list = new ArrayList<>(modifiers.size());
11381145
for (Map.Entry<Attribute, AttributeModifier> entry : modifiers.entries()) {
11391146
Attribute attribute = entry.getKey();
11401147
AttributeModifier modifier = entry.getValue();
1141-
Map<String, Object> entryMap = new HashMap<>();
1148+
Map<String, Object> entryMap = new HashMap<>(4);
11421149
if (attribute.getKey() != null) {
11431150
entryMap.put("attribute", attribute.getKey().toString());
11441151
}

src/main/java/com/pyjavabridge/EventDispatcher.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,8 @@ private void handleBlockExplode(List<org.bukkit.block.Block> blocks, Event event
195195
if (blocks.isEmpty()) {
196196
return;
197197
}
198-
List<PendingEvent> batch = new ArrayList<>();
199-
List<JsonObject> payloads = new ArrayList<>();
198+
List<PendingEvent> batch = new ArrayList<>(blocks.size());
199+
List<JsonObject> payloads = new ArrayList<>(blocks.size());
200200
// Compute the base event payload once and clone per-block
201201
JsonObject basePayload = baseEventPayload(event, eventName);
202202
for (org.bukkit.block.Block block : blocks) {
@@ -264,14 +264,13 @@ private void sendBatch(String eventName, List<JsonObject> payloads) {
264264

265265
private Method getCachedMethod(Class<?> eventClass, String methodName) {
266266
String key = eventClass.getName() + "." + methodName;
267-
Optional<Method> cached = methodCache.computeIfAbsent(key, k -> {
267+
return methodCache.computeIfAbsent(key, k -> {
268268
try {
269269
return Optional.of(eventClass.getMethod(methodName));
270270
} catch (Exception e) {
271271
return Optional.empty();
272272
}
273-
});
274-
return cached.orElse(null);
273+
}).orElse(null);
275274
}
276275

277276
private void tryAddPayload(JsonObject payload, Event event, String key, String... methodNames) {

0 commit comments

Comments
 (0)