Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Context: dotnet/android-libzipsharp#50 When profiling xamarin-android builds with the Mono profiler, I noticed `libZipSharp` is one of the biggest allocators of `byte[]`: Allocation summary Bytes Count Average Type name 251089192 57759 4347 System.Byte[] 94852584 bytes from: Xamarin.Tools.Zip.ZipArchive:Close () (wrapper managed-to-native) Xamarin.Tools.Zip.Native:zip_close (intptr) (wrapper native-to-managed) Xamarin.Tools.Zip.ZipArchive:stream_callback (intptr,intptr,ulong,Xamarin.Tools.Zip.SourceCommand) Xamarin.Tools.Zip.ZipArchive:stream_callback (intptr,intptr,ulong,Xamarin.Tools.Zip.SourceCommand) (wrapper alloc) object:ProfilerAllocVector (intptr,intptr) (wrapper managed-to-native) object:__icall_wrapper_mono_gc_alloc_vector (intptr,intptr,intptr) 25673176 bytes from: Xamarin.Android.Tasks.ResolveLibraryProjectImports:Extract (System.Collections.Generic.IDictionary`2<string, Microsoft.Build.Framework.ITaskItem>,System.Collections.Generic.ICollection`1<Microsoft.Build.Framework.ITaskItem>,System.Collections.Generic.ICollection`1<Microsoft.Build.Framework.ITaskItem>,System.Collections.Generic.ICollection`1<Microsoft.Build.Framework.ITaskItem>) Xamarin.Android.Tools.Files:ExtractAll (Xamarin.Tools.Zip.ZipArchive,string,System.Action`2<int, int>,System.Func`2<string, string>,System.Func`2<string, bool>) Xamarin.Tools.Zip.ZipEntry:Extract (System.IO.Stream) Xamarin.Tools.Zip.ZipEntry:DoExtract (intptr,System.IO.Stream,Xamarin.Tools.Zip.EntryExtractEventArgs) (wrapper alloc) object:ProfilerAllocVector (intptr,intptr) (wrapper managed-to-native) object:__icall_wrapper_mono_gc_alloc_vector (intptr,intptr,intptr) 3780312 bytes from: Xamarin.Tools.Zip.ZipEntry:DoExtract (intptr,System.IO.Stream,Xamarin.Tools.Zip.EntryExtractEventArgs) (wrapper managed-to-native) Xamarin.Tools.Zip.Native:zip_fread (intptr,byte[],ulong) (wrapper native-to-managed) Xamarin.Tools.Zip.ZipArchive:stream_callback (intptr,intptr,ulong,Xamarin.Tools.Zip.SourceCommand) Xamarin.Tools.Zip.ZipArchive:stream_callback (intptr,intptr,ulong,Xamarin.Tools.Zip.SourceCommand) (wrapper alloc) object:ProfilerAllocVector (intptr,intptr) (wrapper managed-to-native) object:__icall_wrapper_mono_gc_alloc_vector (intptr,intptr,intptr) This seems like *a lot* of `byte[]` allocations. To improve this, I added a `<PackageReference/>` to `System.Buffers` and could make use of `ArrayPool`. `libZipSharp` will likely still allocate some large `byte[]`, but things should improve because many will be reused. The changes appear to have saved ~122,523,744 bytes of allocations: Allocation summary Bytes Count Average Type name Before: 251089192 57759 4347 System.Byte[] After: 128565448 31764 4047 System.Byte[] I saw build performance improvements for the Xamarin.Forms integration project, the two tasks heavily using `libZipSharp`: Before: 1881 ms ResolveLibraryProjectImports 1 calls 3406 ms BuildApk 1 calls After: 1795 ms ResolveLibraryProjectImports 1 calls 3150 ms BuildApk 1 calls I would guess this saves ~350ms on an initial build. Incremental builds won't be allocating `byte[]` as heavily, but should see some improvement. I also need to make sure our installers include `System.Buffers.dll` alongside everywhere we have a copy of `libZipSharp.dll`.
- Loading branch information