Performance Improvements
There are several ideas around on how we could improve general performance:
- Encryption stuff with C++ (I'd like to test the Kalium Java wrapper for the NaCl library)
- Caching of stuff locally (like UserProfileManager for the user profile)
- Batching of network messages (similar to the file buffers)
This list should be extended with further ideas.
Encryption stuff with C++ (I'd like to test the Kalium Java wrapper for the NaCl library)
This would certainly improve the performance. However, one of the bin advantages of Hive2Hive is, that it's pure Java. An option would be that the developers can chose between the available crypto-libraries (pure Java but slow, NaCl which is fast, dummy encryption for developing purposes (which does nothing)).
An option would be that the developers can chose between the available crypto-libraries
Of course, that was in my mind. We could hide it behind an interface and let the dev's choose which implementation to take.
I replaced the default Java serialization with Fast Serialization. The project looks very neat and it brings us two improvements (see Benchmark):
- speedup of serialization
- reduced size of serialized objects (better network performance)
To do this I had to tear out the serialization things out of the EncryptionUtil. At the same time, I also moved the hashing functionality to an own class. I didn't do much testing yet, but you can probably feel a performance improvement when running the demo client.
As you can see in the benchmark, Kryo would have been a good alternative. But I didn't chose it because a default constructor at serialized objects is required, what is somehow ugly. Since the serialization is all in a single class (see SerializationUtil), the underlying library can be changed easily.
I also refactored the encryption, but did not change the way it works. Thus, encryption and key generation remains the bottleneck for now.
The serialization has been factorized such that a user can give its own serialization implementation (similar to the encryption). I needed this because Fast Serialization is not Android compatible.
By default, we currently provide two serialization implementations (all nodes of a network should use the same):
- Java serialization
- FST serialization
We'll probably add Kryo soon, because it's fast and Android-compatible. The downside is that it requires default zero-argument constructors (can be private).
An own encryption implementation can be injected by providing an implementation of the following classes:
- IH2HEncryption
- ISecurityClassProvider (used for proper serialization with FST. If Java default serialization is used, this implementation is not necessary).
- IStrongAESEncryption (optional, used for AES encryption with keys > 128 bit)
I just saw that the injected IH2HSerialize implementation was just used for encrypted objects in the DHT. Unencrypted objects (like Locations, UserPublicKey) were not serialized with it. This has been resolved and the performance should be slightly improved.