Is using Serializable in Android bad? - android

I've been reading a lot of posts and articles extolling the speed of Parcelable over Serializable. I've been using both for a while to pass data between Activities through Intents, and have yet to notice any speed difference when switching between the two. The typical amount of data I have to transfer is 5 to 15 nested objects with 2 to 5 fields each.
Since I have about 30 classes which must be transferable, implementing Parcelable requires a lot of boilerplate code that adds maintenance time. One of my current requirements is also that the compiled code should be as small as possible; I expect that I could spare some space by using Serializable over Parcelable.
Should I use Parcelable or is there no reason to use it over Serializable for such small amounts of data? Or is there another reason why I shouldn't use Serializable?

For in-memory use, Parcelable is far, far better than Serializable. I strongly recommend not using Serializable.
You can't use Parcelable for data that will be stored on disk (because it doesn't have good guarantees about data consistency when things change), however Serializable is slow enough that I would strongly urge not using it there either. You are better off writing the data yourself.
Also, one of the performance issues with Serializable is that it ends to spin through lots of temporary objects, causing lots of GC activity in your app. It's pretty heinous. :}

Continue to use Serialization. You'll see lots of people online who will tell you that Serialization is very slow and inefficient. That is correct. But, one thing you never want to do as a computer programmer is take any comment about performance as an absolute.
Ask yourself if serialization is slowing your program down. Do you notice when it goes from activity to activity? Do you notice when it saves/loads? If not, it's fine. You won't get a smaller footprint when you go to a lot of manual serialization code, so there is no advantage there. So what if it is 100 times slower than an alternative if 100 times slower means 10ms instead of 0.1ms? You're not going to see either, so who cares? And, why would anyone invest massive effort into writing manual serialization for 30 classes when it won't make any perceptible difference in performance?

Everybody just blindly states that Parcelable is better and faster, than Serializable, but nobody has tried to support his statements with any proofs. I decided to test this myself and I got very interesting results.
Usual Java serialization on an average Android device (if done right) is about 3.6 times faster than Parcelable for writes and about 1.6 times faster for reads.
You can check my test project here: https://github.com/afrish/androidserializationtest

Has anyone considered serialization using JSON and passing the data as a string? GSON and Jackson should be efficient enough to be a competitor to Parcelable as well as Serializable.

Related

Measuring performance with parcelable

Currently, I am having around 100 Pojo's which implements serializable and passed throughout the app, Since I am expecting more to come as the app grows & it will be better to make use of parcelable.
Will there be any significant performance gain and how can I measure it?
I know about android studio profiler etc. but not really aware which area I will see the performance gain i.e overall app speed, memory consumption etc.
Also, any thing to take care of while making this change?
According to Philippe Breault's benchmark, Parcelable is way faster than Serializable. He tested it on 3 different devices, with Android versions 2.3.3 and 4.2.2.
You can see the results below.
Nexus 10 Serializable: 1.0004ms – Parcelable: 0.0850ms - 10.16x faster.
Nexus 4 Serializable: 1.8539ms – Parcelable: 0.1824ms - 11.80x faster.
Desire Z Serializable: 5.1224ms – Parcelable: 0.2938ms - 17.36x faster.
Those numbers are for a single object, passed through a Bundle 1000 times around. If you're expecting to add 100+ more, things will escalate quickly.
Serializable is a standard Java interface, and it tends to leave a lot of temporary objects behing, which can trigger many GC events.
Parcelable on the other hand, is an Android interface, that was conceived to tackle performance issues, and it achieves that by not using reflection on the serialization. Thing is, you have to define the serialization yourself. But you'll get a huge performance difference compared to Serializable objects.
You can read more about Parcelable on the docs.
Also, related answer on why you should use Parcelable.

Android performance: useless global variables vs inheritance

Let's say I have an object A and B that extends A.
B has global variables that are irrelevant for A (an array, and a few counters).
Since explicit casting is costly (I'm not sure how much), would it be better, from a sheer performance pov, to only create a class A and create an array only if needed so that I don't have to cast?
I guess the question is, do global variables of an object cost anything at all, even if unused?
Edit: forgot to add the most important... functions, obviously.
In recent years, inheritance is often treated like code-smell, because it can lead to different problems:
https://dzone.com/articles/is-inheritance-dead
If we talk in pure performance term, an empty array takes about 8 bytes in RAM (4 bytes store length and 4 bytes a reference, but it is a little platform-dependent: How much space does an array occupy?). So, even if you have a thousand of such objects, one array field will take approximately 1_000 * 8 bytes ~ 8 KBytes in RAM.
As you probably know, nowadays phones usually contain > 1 GByte of RAM. However, don't forget that your app usually can take from 60 to 192 MBytes of RAM (Detect application heap size in Android).
In any case, it is more than enough not to count every little field that you are adding to your class.
However, going back to my first statement, I suggest you to think about solving the problem using composition instead of inheritance, as it is suggested in Effective Java
Update
About performance, I would suggest you to read this topic: The performance impact of using instanceof in Java Are you sure that you need such type of premature optimization? Or is it more a theoretical question than practical?
Obviously, No, don't blend both classes in one class A. Never. as you mentioned, the array is irrelevant to class A. so don't put it to A.
next, in your case, downcasting is a point that tells: Wait programmer, do you want to think a little more? sometimes, there is a solution that does not need downcasting. but
Since explicit casting is costly
I don't think so. There is some benchmark and expansions that tells us, no there is no huge difference here.
expansion
benchmark
So. follow the first solution...
Since explicit casting is costly (I'm not sure how much), would it be
better, from a sheer performance pov, to only create a class A and
create an array only if needed so that I don't have to cast?
Besides the dubious claim about the cost of casting, maybe I'm misunderstanding but that raised red flags for me. If your design involves casting an object to a subclass it could probably be better designed in some other way. I can't say what without seeing more, but the need to cast is often a sign of design failure*. As Gaket suggests, composition could be better, or there might be some other change - factory pattern perhaps?
Secondly, you should only be concerned about performance if you have noticed a performance issue, or have a real reason to think there will be one. Almost anything the processor does is going to be plenty fast unless it's done many times over (like millions). Your performance issues (unless your program is unusual in some way) are most likely going to be I/O or memory. Then after you're identified a performance bottleneck, the steps to fix it are:
measure
set a goal
fix
measure
Don't leave out any steps.
*I know casting is a central part of Android programming because you have to cast Views every time you get them, and I wonder if there might have been a better way to do that, but that's what we're stuck with

Creating a Serializable ArrayMap

I'm a newbie to Android, however I'm not entirely new to Java. From what I can tell, the ArrayMap should be used over the HashMap due to less memory used/performance increase. I'm not entirely sure when I should use one over the other beyond that, however while attempting to send an ArrayMap over a Bundle/Intent, I noticed that I was unable to do so, yet I could with a HashMap.
So, I thought, instead of just succumbing to using HashMap, especially when it's not necessary to, I'll create my own Serializable ArrayMap, however I'm unsure as to how to go about it.
All I know is that I implement three methods, readObject, writeObject, and readObjectNoData, all which have a Stream as an argument. I'm assuming I have to go through each item in the ArrayMap, then write it to the output stream and read from the input stream to recreate the ArrayMap. What I want to know is... how I should go about doing so.
I'm sorry if there is a duplicate question, but I can't really find any at all. So I'll start off with an example to fend off any "YAGNI" (You Aren't Gonna Need It). For one of my projects, I maintained a nested ArrayMap of objects, with said objects being in the thousands, with nested key-values to reduce collision greatly. I can't go too far into it, as it was for a recent school project. I wanted to be able to preserve the data structure over the life cycle of the application, including onDestroy of MainActivity, without having to parse everything all over again.
My solution ended up being to create a constant (static final) ArrayMap and access that, which worked, but it feels like I'm going against the philosophy of Android Development. Also I'm assuming that when MainActivity is destroyed the constant is also destroyed as well, yet with a saved bundle, it will be preserved, which is what I want.
I'm getting off topic... anyway, I want to create a Serializable ArrayMap, but I have a lot of questions regarding it. For one, what would be the best format to represent the objects nested inside of an ArrayMap? JSON would be my guess, although I've never actually done anything with it before. Then, how do I get the information from the objects nested inside? Do I enforce that only certain objects that implement an interface I declare may be added to the map? Then HashMap doesn't have this requirement. Do I use reflection to obtain each field and value, but then isn't that super slow?
I cannot use any third-party libraries, however I would love to do this from scratch regardless as it feels like a good way to learn more, does anyone have any tips/ideas on how to properly approach this? Thank you in advance!

Scala on Android: best strategy for avoiding global data?

Suppose you have multiple activities in an app and need to share data. A pretty common pattern for Android developers it seems is to have some sort of singleton object (optionally attached to the Application singleton), and share data globally using that. That's bad enough in Java, but looks really ugly in Scala.
For message passing you can use Intents if your data consists of primitives. But what about your main domain model? I'd like to be able pass very complex objects. It seems I might be able to do that using Parcelable serialization, but I'm not sure how fast that is (my objects are data-heavy) and if it works well with Scala? Has anybody tried this?
Another idea would be to use the "HashMap of WeakReferences to Objects" strategy where the passed messages are references -- you've still got global data but access is guarded. Maybe I can get some opinions on that too, not just from Android folk but also some Scala folk.
The way I solved this was to include the Akka library in my app, and turn the global objects into messages that are passed between activities.
It seems to work OK, but not a lot of people are using Akka on Android so far and it's difficult to find best practices. If people have any comments about this strategy, let me know.

android, object oriented programing vs designing for performance

I am a complete noob to android but I have been programing c# for a long time. I am writing an android application and have gotten to a point where the c# programmer in me wants to start creating a loosely coupled design and and moving code into different layers, using interfaces, etc.
But then I stumble upon the Designing for performance guidelines it is telling me to avoid object creation and then it also is saying to optimize judicially.
Do I just build based on good design and then deal with performance issues as they come up?
The last thing I want to do is go through the work of building a application and have it perform poorly. Can someone point me to some examples of application that are designed well and have good performance or just make some recommendations?
Thanks
I've found AndEngine to be fairly well designed and it has to be concerned with performance since it is a game development library -- so you might pull down a copy of it and read the source.
In the "Designing for performance" document, I would point out this statement:
Note that although this document
primarily covers micro-optimizations,
these will almost never make or break
your software. Choosing the right
algorithms and data structures should
always be your priority, but is
outside the scope of this document.
An example of this would be creating a particle system. A good way to model it is to have a ParticleSystem object that holds a collection of Particle objects...maybe those Particles implement a Particle interface...this is not the place to avoid object creation. However, for performance reasons, you will want to optimize the ParticleSystem to recycle Particle objects rather than creating them from scratch every time you spawn one.
Personally, I haven't found performance to be much of a limiting factor but I suppose that will really depend on what type of app you're building.
My opinion is to build a suitable design first, test the performance, and optimize from there.
Pay more attention to Donald Knuth's quote that appear in the same article:
"We should forget about small
efficiencies, say about 97% of the
time: premature optimization is the
root of all evil.root of all evil."
Then if you are dealing with the other 3% you'll see...
As a general rule, the thing to do is keep the data structure as simple and normalized as you can. Like don't just throw in hash table data structures just because they are easy to grab. Know how to do profiling (here's my method) and if you have a real performance problem then fix it. Otherwise, the simpler the better, even if that means simple arrays, lists, and O(N) loops.
The reason to keep the data structure normalized is, if it is not, then it can have inconsistent states, and you will have a strong temptation to write notification-style code to try to keep it consistent. Those can be real performance killers. If you do those, the profiling will tell you it that's what is happening.
If you must have redundant data, I think it's better to be able to tolerate some temporary inconsistency, that you periodically repair by passing through the data. This is better than trying to intensely guarantee consistency at all times by notifications.
Another problem with unnormalized data structure is it can have lots of object creation and destruction. That also can be a real performance killer, although you can ameliorate it with the pool technique.

Categories

Resources