Comments (9)
My understanding is that the ~1.5kb "memory penalty" for enums happens per declaration
Hmm, maybe I misunderstand. I'm thinking that quite a bit of that 1kb comes from the base class and associated code, which (thanks to object orientation) are shared across declarations. Certainly, methods like Enum#values()
get deduplicated during dexing.
As you say, it's not exactly the case that using a few enums will ruin your app. I still hold the belief that the safety provided by enums outweighs their cost on-device. I certainly wouldn't use such a feature as int-enums myself, but wouldn't say no to having an option (non-default) to generate them.
from thrifty.
I'm not working on a project that involves Thrift on Android atm so I won't
be able to try it in the near future. But thanks a lot for implementing it.
On Fri, 11 Nov 2016, 02:15 Ben Bader, [email protected] wrote:
@futtetennista https://github.com/futtetennista I don't know if you're
still interested in this feature, but I slapped it together just now. It's
available to play with at
https://github.com/benjamin-bader/thrifty/tree/int-enums. I'm probably
not going to publish this as a snapshot soon; it's such a far-reaching
change that the current test setup can't do both Java and IntDef enums.If you do try this out, I'd be curious what it does to your total method
count and to your .dex size. My suspicion is that it won't do much, due to
the helper classes. If we decided to forego string names, that would change
things considerably.—
You are receiving this because you were mentioned.Reply to this email directly, view it on GitHub
#20 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AATuwz8hwtw1i6xq_9PrGZzQ6HTUKKGZks5q88GogaJpZM4H1Ds2
.
from thrifty.
I've always thought that video's argument to be a bit of a strawman. The overhead of enums looks bad only compared to an impossibly-tiny dex binary. Additionally, that huge 1kb hit only really applies to the first enum you add; the bulk of the added code in your .dex is shared across all other enum classes. In any event, in practice your actual code (to say nothing of the libraries you use) will utterly dwarf the size of code dedicated to enums.
Ints help you avoid that overhead, but at what cost? If you just use ints in an ad-hoc fashion, you lose all semblance of type-safety. To regain some measure of sanity, you must:
- Find an appropriately-named class to host your ints (extra overhead of a non-instantiated class)
- Declare a custom
@IntDef
annotation, e.g.@NotAnEnum
- Use
@NotAnEnum
everywhere such an int occurs
My opinion (and it is an opinion) is that the extra few kb of memory is a small price to pay for safer, more readable code. You might argue that, as a library, thrifty doesn't (or shouldn't) have the luxury of deciding how much memory it should be able to use. That's a valid point, but I'd argue that thrifty is already quite opinionated, and its opinions impose a burden on consumers. Pervasive use of builders, for example, doubles the generated method count as well as bulking up the size of the .dex file - in the name of increased safety.
TL;DR: I'd vote 'no' on this one, but if one were to feel strongly I wouldn't say no to a patch - so long as it were off by default (i.e. regular enums would still be generated unless an --int-enums flag were given)
from thrifty.
The topic always puzzled me I must admit and by reading posts and comments around the internet it looks like using or not using enums should be evaluated on a per-app basis and that there is no bullet-proof solution. I'm a big fan of enums and type-safety myself so I totally agree with you on that. On the other hand I'd be curious to see if there are any substantial improvements by not using enums in our app, since we use enums extensively. I might spike this if I find some free time.
Could you elaborate on:
Additionally, that huge 1kb hit only really applies to the first enum you add; the bulk of the added code in your .dex is shared across all other enum classes.
My understanding is that the ~1.5kb "memory penalty" for enums happens per declaration (but again that doesn't mean that your apk size will explode just because your using a bunch of enums).
from thrifty.
I finally have some space in my schedule to look in to this. It is certainly doable.
One feature of enums that I treasure is the name()
method - so very useful for logging! Also a prerequisite for any textual Protocol
(such as the current SimpleJsonProtocol
). We will need a method to get a name from an int-enum.
Another question on my mind is how all of this should be organized. Most current uses of int-enums naturally live within e.g. a Layout or a Service; we would be generating domain values. It would be confusing (to me, at least) to make up some generic IntEnums
class to hold disparate Thrift enumeration values.
In light of this, I'm considering the following unorthodox API design - any feedback would be most welcome:
Thrift:
enum Foo {
BAR = 1,
BAZ = 2,
QUUX = 3
}
@IntDef({Foo.BAR, Foo.BAZ, Foo.QUUX})
@Retention(SOURCE)
@Target({PARAMETER, METHOD, LOCAL_VARIABLE})
public @interface Foo {
int BAR = 1;
int BAZ = 2;
int QUUX = 3;
// If only we had Java 8 on Android and default interface methods!
final class Helper {
private Helper() {
// no instances
}
public static String nameOf(@Foo int value) {
switch (value) {
case Foo.BAR: return "BAR";
case Foo.BAZ: return "BAZ";
case Foo.QUUX: return "QUUX";
default: return null;
}
}
}
}
Things to like:
- It's lightweight relative to actual enums
- The end-user "API" is quite familiar, i.e. "TypeName"."MEMBER_NAME"
- Self-contained
Things not to like:
- Interface-constants antipattern, now in
@interface
flavor Helper
is painful:Foo.Helper.nameOf(Foo.BAR)
- The extra Helper classes eat up quite a bit of the savings compared to plain enums
The last point in particular worries me. An alternative to helper-per-int-enum might be to consolidate all enum helper-methods in a package into one class, e.g. com.foo.bar.EnumHelper
, with methods like public static String nameOfFoo(@Foo int value)
. Definitely not at all a fan of this API, but it would minimize the bloat.
The above design is my best thought for the moment, but depending on the costs incurred I'm not sure that it is worth implementing. Thoughts?
from thrifty.
As a reminder to myself, this design is blocked pending the next release of JavaPoet - square/javapoet/issues/467 is fixed in master, but not shipped, so no fields in annotations at present.
from thrifty.
Today's release of JavaPoet 1.8 finally includes the bugfixes needed to move this forward.
The next step is to just try it and see what happens!
from thrifty.
@futtetennista I don't know if you're still interested in this feature, but I slapped it together just now. It's available to play with at https://github.com/benjamin-bader/thrifty/tree/int-enums. I'm probably not going to publish this as a snapshot soon; it's such a far-reaching change that the current test setup can't do both Java and IntDef enums.
If you do try this out, I'd be curious what it does to your total method count and to your .dex size. My suspicion is that it won't do much, due to the helper classes. If we decided to forego string names, that would change things considerably.
from thrifty.
I don't think this will ever land - absent any user interest, I'm personally not inclined to either adopt or maintain this feature.
from thrifty.
Related Issues (20)
- Struct-valued constants are not yet implemented HOT 5
- Deprecated Gradle APIs in use, will break in Gradle 8 HOT 1
- Add Java codegen for struct-valued constants
- Question/feature request: Add header/comments to each file HOT 4
- This repo is missing important files
- Using thrifty-plugins with the thrifty gradle plugin HOT 9
- Add gradle-plugin API for TypeProcessor plugins
- Cyclical references in struct-valued constants? HOT 4
- Expose referenced Constants
- Schema should sort constants in dependency order
- Const refs list should be `distinct()`
- Support comments for struct properties HOT 2
- iOS support
- Gradle plugin ignores FieldNameStyle specification for Kotlin code gen HOT 1
- Fork! HOT 2
- Support iOS Simulator Arm64 Target
- [email protected] HOT 1
- BinaryProtocol hard-codes strict read/write properties
- What happened to the DecoratingProtocol? HOT 1
- Const definitions referencing imported consts cannot be loaded HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from thrifty.