Giter Site home page Giter Site logo

Comments (12)

frankiesardo avatar frankiesardo commented on July 23, 2024

I'm not big on paceler, see #20 for the discussion (especially towards the end).

I suggest you use instead @AutoParcel which is far more performant and fully composable with icepick.

from icepick.

JackDigital avatar JackDigital commented on July 23, 2024

It is fine, but I use ormlite and gson. I'm really interested in Auto*, but this can't be done with it.

from icepick.

frankiesardo avatar frankiesardo commented on July 23, 2024

I feel your pain. There's an ongoing discussion with Google to add easy to extend plugins to AutoVaulue so that things like Gson or ORM libraries can integrate their own functionality on top of it. When this solution would be ready it's gonna be a killer app for AutoValue, but as you see we shouldn't hold our breath waiting for a release soon.

Still, this is the right way forward and I'm going to support it.

from icepick.

johncarl81 avatar johncarl81 commented on July 23, 2024

@frankiesardo, I was curious about your remark that AutoParcel was more performant than Parceler so I did a little performance analysis which you can find here: https://github.com/johncarl81/parceler/tree/master/examples/performance

Here are the numbers I came up with on a real device:

Name Time to Serialize
Parceler 404935.1442ns
Parcelable 430859.1484ns
Parceler with AutoValue 489583.3968ns
AutoParcel 1037421.0286ns
Gson 1533837.9367ns
Serializable 3059908.4384ns

The numbers show that Parceler and AutoParcel have comparable performance (within a factor of 10) both when dealing with both Parceler and AutoParcel immutable beans (Parceler supports AutoValue) and Parceler mutable beans.

from icepick.

johncarl81 avatar johncarl81 commented on July 23, 2024

@JackDigital, I went ahead and rebased my previous PR against the latest Icepick. You'll find this version of Icepick that transparently wraps and unwraps Parceler @Parcel annotated beans here: https://github.com/johncarl81/icepick/tree/parceler_support. If you're interested in a version available from Maven central, let me know.

from icepick.

frankiesardo avatar frankiesardo commented on July 23, 2024

@johncarl81 thanks for taking the time of setting up this tests, I find the result very interesting. I assumed Parceler would always be slower because of the level of indirection provided by wrap and unwrap, but it turns out the simple strategy of writeObject adopted by AutoParcel is the real bottleneck.

But that result is not very realistic for a common usage of an application: you'll never gonna need to write 10000 times the same class, you're more likely to write 10 times 50 different classes and that's where Parceler would suffer more due to reflection, am I right?

Anyway I don't have anything against Parceler per se, it's just that I like AutoParcel more in the way it composes with everything else because it is agnostic: with AutoParcel you actually instantiate a Parcelable object.

Once Google stabilises its AutoValue API it is likely I'm gonna rewrite the Parcelable code to use types instead of the generic writeObject. But as you've shown the current speed is quite acceptable.

from icepick.

johncarl81 avatar johncarl81 commented on July 23, 2024

You're correct, writeObject (writeValue?) is a bottleneck and one I've tried to avoid in Parceler. If you look at the source code behind it, it's a series of conditionals, each hitting instanceof.

I agree this benchmark isn't very realistic, the reason I repeated the tests 10000 times is to get solid averages out of the various techniques.

Serializing different classes (like your example of 10 times for 50 classes) should have similar performance to serializing one class repeatedly. Parceler uses reflection sparingly. Behind the Parceler wrap/unwrap cycle is a generated dictionary class (see Parceler$$Parcels) that effectively avoids reflection except for the very first lookup call of the dictionary itself. If you'd like to try it out I'd love to hear about the results.

I'd be interested in collaborating on the AutoValue Parcelable plugin, when AutoValue supports that sort of thing. Let me know if you want my input.

from icepick.

ZakTaccardi avatar ZakTaccardi commented on July 23, 2024

@frankiesardo AutoParcel can only be used with immutable objects, I believe. When you do not need a mutable object - it's by far the best scenario.

I find the most important place to use a parcelable object is in a ViewModel - which will often require it being a mutable object. For example, I have a Quiz view model, in which the active question of the quiz changes as the user progresses through it. AutoParcel will unfortunately not work for this use case, to my knowledge.

Being able to use @Iclicle on an object is the greatest thing ever. It would be nice to be able to combine that somehow with a mutable object, without having to write the Parcelable implementation yourself

from icepick.

frankiesardo avatar frankiesardo commented on July 23, 2024

The information may change, but it's important that the models remain immutable. If you need to capture a Quiz changing value, then I would create each time a new Quiz object (and propagate the new model with something like Otto). Uncontrolled mutability causes too many bugs.

from icepick.

ZakTaccardi avatar ZakTaccardi commented on July 23, 2024

going to use VM to show that an object is a view model.

a QuizVM is a pretty large object though.

  • has a name field
  • an int currentQuestion
  • List<QuestionVM> which each has up to 4 AnswerVMs .

Those AnswerVMs have:

  • a boolean isCorrect
  • a state associated with it (whether the question should reveal that its a correct answer or not or not)
  • and whether a specific AnswerVM has been selected by the user.

In total, with a single quiz of 10 questions with ~4 possible answers - you are looking at the recreation of up to 40-50 objects every time you change a single value if you want them to remain immutable. To me, it seems mutability is the way to go here, as long as you are careful about how you pass this object across threads. I am actually constructing it initially on a background thread, and then accessing /mutating it only happens on the main thread afterwards.

propagate the new model with something like Otto

What exactly do you mean by this? Sending the construction of this object to a background thread?

Ultimately, something as easy to use as @AutoParcel for mutable objects would be nice. I would even settle for an IDE plugin that would auto-generate parcelable code based on the class fields.

from icepick.

johncarl81 avatar johncarl81 commented on July 23, 2024

@ZakTaccardi, there are quite a few options for generating Parcelables. In fact there is a plugin along the lines of what you mentioned: https://github.com/mcharmas/android-parcelable-intellij-plugin

from icepick.

frankiesardo avatar frankiesardo commented on July 23, 2024

@ZakTaccardi If, say, you're adding an Answer object to an immutable Quiz model, then what you're creating underneath is:

1 A new Quiz object. name and currentQuestion point to the old ones.
2 A new List<Question>. All other questions that are not the one you're modifying point to the old ones.
3 A new Question with everything pointing to the old question except for the Answer you're adding.
4 The Answer object.

So you're really just creating 4 objects instead of 1. Your approach makes a lot of sense and mutability if controlled, as in your case, it's temptingly easy. Or, as in the case of animations, it's the only viable performant option. Still, once you start to enforce immutability on more and more areas of your code you'll find it cleaner and easier to understand. It's like passing around Strings instead of StringBuffers: you'll never have to worry about somebody changing what's on the other side of the pointer.

If you're interested to explore this route you can have a look at Persistent data structures that provide efficient structural sharing between immutable collections https://github.com/krukow/clj-ds. Or, yeah, just use the intellij plugin :octocat:

from icepick.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.