3
0
mirror of https://github.com/Qortal/altcoinj.git synced 2025-02-07 06:44:16 +00:00

Replace reflection with an if ladder for deserialization, as reflection was dominating the profiles (60% of all time spent downloading the chain). Takes us from around 250-300 blocks per second to over 400.

This commit is contained in:
Mike Hearn 2011-07-06 15:44:20 +00:00
parent d654a33376
commit 16f2fae0ce

View File

@ -51,8 +51,6 @@ public class BitcoinSerializer
private boolean usesChecksumming;
private static Map<Class<? extends Message>, String> names = new HashMap<Class<? extends Message>,String>();
private static Map<String, Constructor<? extends Message>>
messageConstructors = new HashMap<String, Constructor<? extends Message>>();
static {
names.put(VersionMessage.class, "version");
@ -75,14 +73,6 @@ public class BitcoinSerializer
public BitcoinSerializer(NetworkParameters params, boolean usesChecksumming) {
this.params = params;
this.usesChecksumming = usesChecksumming;
// some Message subclasses can only be sent for now, ignore missing constructors
for (Class<? extends Message> c : names.keySet()) {
Constructor<? extends Message> ct = makeConstructor(c);
if (ct != null) {
messageConstructors.put(names.get(c),ct);
}
}
}
public void useChecksumming(boolean usesChecksumming) {
@ -217,17 +207,36 @@ public class BitcoinSerializer
}
try {
Constructor<? extends Message> c = messageConstructors.get(command);
if (c == null) {
throw new ProtocolException("No support for deserializing message with name " + command);
}
return c.newInstance(params, payloadBytes);
return makeMessage(command, payloadBytes);
} catch (Exception e) {
throw new ProtocolException("Error deserializing message " + Utils.bytesToHexString(payloadBytes) + "\n", e);
}
}
private Message makeMessage(String command, byte[] payloadBytes) throws ProtocolException {
// We use an if ladder rather than reflection because reflection is very slow on Android.
if (command.equals("version")) {
return new VersionMessage(params, payloadBytes);
} else if (command.equals("inv")) {
return new InventoryMessage(params, payloadBytes);
} else if (command.equals("block")) {
return new Block(params, payloadBytes);
} else if (command.equals("getdata")) {
return new GetDataMessage(params, payloadBytes);
} else if (command.equals("tx")) {
return new Transaction(params, payloadBytes);
} else if (command.equals("addr")) {
return new AddressMessage(params, payloadBytes);
} else if (command.equals("ping")) {
return new Ping();
} else if (command.equals("verack")) {
return new VersionAck(params, payloadBytes);
} else {
throw new ProtocolException("No support for deserializing message with name " + command);
}
}
private Constructor<? extends Message> makeConstructor(Class<? extends Message> c) {
Class<?> parTypes[] = new Class<?>[2];
parTypes[0] = NetworkParameters.class;