Reputation: 2952
I have a C# app that gets ahead of time compiled to the native iOS code using monotouch (Xamarin)
Some of the libraries I link in use generics. However, it turns out that this method of compiling causes significant code bloat because it uses the C++ style of template code generation generating functions for List<int>
, List<string>
etc.
What I want is the Java style of generics where generics are used for compile time checking but at runtime the code only contains functions for List
and not for each of the templated types.
Note: This is not an issue with using C# in the .Net CLR, as explained here. The issue arises because code is compiled AOT to the native binary instead of intermediate language. Moreover runtime type checking for generic methods is fairly useless since the binary is native.
Question: How do I disable generics, i.e. replace all occurrences of List<T>
with List
, during compilation? Is this even possible?
Upvotes: 2
Views: 567
Reputation: 19345
This is not possible.
On Java it's possible because they don't have value types, only classes (you can emulate this behavior by not using value types yourself, only use List<object>
(or an object
subclass), in which case the AOT compiler will only generate one instantiation of List).
You're also not entirely correct saying that it's not an issue with the .NET CLR; the difference between the .NET CLR and Xamarin's AOT compiler is that the AOT compiler can't wait until execution time to determine if a particular instantiation is needed or not (because iOS doesn't allow executable code to generated on the device), it needs to make sure every possible instantiation is available. If your app on the .NET CLR happened to need every possible generic instantiation at runtime, then you'd have a similar problem (only it would show up as runtime memory usage, not executable size, and on a desktop that's usually not a problem anyway).
The supported way of solving your problem is to enable the managed linker for all assemblies (in the project's iOS Build options, set "Linker behavior" to "All assemblies"). This will remove all the managed code from your app you're not using, which will in most cases significantly reduce the app size.
You can find more information about the managed linker here: http://developer.xamarin.com/guides/ios/advanced_topics/linker/
If your app is still too big, please file a bug (http://bugzilla.xamarin.com) attaching your project, and we'll have a look and see if we can improve the AOT compiler somehow (for instance we already optimize value types with the same size, so List<int>
and List<uint>
generate only one instantiation).
Upvotes: 4