XLog – minimalistic logger PCL library for .NET, WP8, UWP and Xamarin

Hi there,

In the last project i participate in, we have all logic in PCL libraries (78 profile). 1.5 years ago there was only one PCL logger – MetroLog. It was partially from log4net/NLog and contained too much async/await logic (mostly IO related), which is too expensive for mobile devices, especially if app performs very detailed logging as our app does.

So we outlined few goals for a perfect logging library:
1. Very small in terms of lines of code.
2. Minimal footprint on IOS IPA size
3. Very fast with minimal possible amount of memory allocations
4. No dependencies except for .NET
5. Support of WP8, Xamarin, UWP
6. Support categories

My colleague Oleg Ilyin wrote an implementation that satisfied those goals, which i optimized a little bit and uploaded to github.
1. We have a library that has ~200 lines of code according to Visual Studio metrics.
2. .NET dll size is ~20kb, IOS binary footprint is <50kb for ARMv7+ARM64.
3. Logging one message to file produces 2 memory allocations, which is much less that NLog/MetroLog do

Code is on github – https://github.com/Belorus/XLog/wiki

Advertisements

.NET Exceptions performance

Hi there!

I made few measurements with cool DotNetBenchmark library written by Andrey Akinshin:
1. I’m awaiting async method that throws deep in callstack and after catching i get StackTrace
2. I’m awaiting async method that throws deep in callstack
3. [COMPARISON ONLY] I’m awaiting async method that returns deep in callstack (without exception)
4. I’m calling normal method that throws deep in callstack
5. I’m calling normal method that throws deep in callstack and after catching i get StackTrace

Code is here (don’t forget to add DotNetBenchmark library, i used 0.78 from nuget)

For stack depth = 100 results are following

Clipboard02qwe

For stack depth = 10 results are following

Clipboard03

For stack depth = 1 results are following

Clipboard013

Clipboard02

CAUTION: Logarithmic scale!

From measurements we can see:
1. Getting stacktrace can slowdown your exception handling code significantly for deep stacks.
2. awaiting methods is very slow itself and exceptions don’t influence on its performance (if not to get stacktrace)

.NET Finalizer performance

Hi there!

During my eternal fighting with .NET performance i decided to check what performance impact does finalizer give.
The easiest way is to write isolated test.

In short, finalizer is symmetrical to ctor optional special method that is called when object is ready to be Garbage Collected on a special finalizer thread. It should be used to free unmanaged resource, and it is better not to touch any managed resources from it, because they can be already GCed.

In my test i create 10,000,000 instances of MyClass and either
1. Store them all in list so they all get to gen2
2. or just forget about them to let GC collect then during gen0 collection

My second research dimension covers finalizability.
a. MyClass has empty Dispose
b. MyClass has empty finalizer and have GC.SuppressFinalize in Dispose
c. MyClass has empty finalizer without GC.SupressFinalize being called

______a                 b                   c

1.     1400ms       2950ms        4300ms

2.       85ms         1000ms        2850ms

The code is here
I ran it on AMD FX-6200 4.4Ghz without CPU affinity.

This shows that
1. allocating/collecting shortliving objects without finalizer is very cheap.
2. forgetting to call SupressFinalize can significantly reduce your performance (finalizer doesn’t allow collecting shortliving objects immediately (in gen0) but adds them to finalization queue and moves to gen1 where they are collected after finalizer is called)

.

string.Join

Hi there 🙂

Today is the Independence day in Belarus (hooray :)) and i have spare time to look at app performance a bit.

I’ve been lookin thru the code and found out that many of method that accept collection work with IEnumerable<T> for better flexibility. Sounds like good following of rule “Relax preconditions, strenghten postconditions”. But quite often i have a materialized collection with data(not yield-based generator) like List<T> or and array.

 

I found a place where i initially get string[] but then pass it as IEnumerable<string> and call string.Join over it.

Clipboard01

Basically there are 5 overloads of string.Join (the second is actually generic string.Join<T>)

Clipboard02

And i used the first one. Huh, quite interesting what is the difference between the one that works with array and the one that works with IE<string>.

First of all quite simple microbench:

Clipboard03

(If u’re interested in those red lines under Console.WriteLine method – have a look at awesome performance fighting plugin for R# HeapView)

Simply changing .ToArray() to .ToList() changes the overload. Results are following:

Array – 73ms    81GC gen 0 collections
List –    115ms    202GC gen 0 collections

IEnumerable based implementation of string.Join simply creates StringBuilder and appends strings one by one.

Array based impl runs over provided array and calculates the total length of final string with separator, creates string  with preallocated char buffer of appropriate length (using both internal  and external FastAllocateString(int length) method) and then does unsafe(in terms of C#) memcpy to that preallocated buffer of every string from the array.

 

As for me, i’d use make my code a bit less nice in terms of preconditions and use arrays a bit more often. One more cool thing about using concrete collection types (T[]/List<T> instead of IEnumerable<T>/IList<T>) – they have struct enumerator, and iterating over them is faster (non-interface call) and do no heap allocations (passing struct as interface (IEnumerator) automatically boxes it, which is pretty expensive).

 

Have a nice day!

Windows Phone image placeholder

Hi,

I think everyone would agree that showing a cute placeholder during long image loading is a good idea.

There are couple of solutions in the internet. My favourite is this – http://compiledexperience.com/blog/posts/image-placeholder-control-with-arbitrary-content . Unfortunately i encountered couple of issues with it when used it in virtualized lists. Image was never loaded, or even the placeholder disappeared.

The easiest way to reproduce is to scroll really fast and to navigate away from the page and then return back. When we navigate away – the page gets unloaded and imageOpened event doesn’t fire – this breaks control logic.

I modified code slightly so it can be used in virtualized lists.

https://www.dropbox.com/s/4ji449yfut2sd3t/ImagePlaceholder.zip?dl=0

Determine internet connection speed of the device.

Hi again,

Some day i was staying in metro and testing the app i’ve been working on.  Something went wrong. Issue was that images were not loaded as device was connected to the internet via GPRS.

App should load smaller images.Luckily server supports multi-res image output.

I defined 4 important for us states
11-04-2013 17-58-15

There are 3 ways of getting conenction speed on device. And only 1 of them works properly.
1. HttpWebRequest and WebRequestExtensions.GetCurrentNetworkInterface (not reliable)
2. DeviceNetworkInformation.ResolveHostNameAsync (breaks tombstoning)
3. Socket and SocketExtensions.GetCurrentNetworkInterface

The third option works like a charm.

Here you can see how socket to Googles Public DNS server is opened and NetworkInterfaceInfo is extracted. Speed assumptions are based on NetworkInterfaceInfo.Bandwidth
11-04-2013 18-17-20

Basing on ConnectionSpeed and on DeviceSpeed
11-04-2013 18-04-02

we decide what image to load via nice matrix
11-04-2013 18-05-54

All the code is in the Zip file on the dropbox.
https://www.dropbox.com/s/5ib47l93j6nwg1v/ConnectionSpeed.zip

Important:  Don’t forget to invoke ConnectionSpeedManager.CheckConnection() in Apps OnLaunch and OnActivate methods

Dealing with deactivation during navigation.

Hi,

Probably every WP7 developer had to deal with this nasty issue.

Steps to reproduce:
During navigation deactivate app via central hardware button (Win). Important: Reproduces only on Device

Issue:
After activating app back InvalidOperationException with message “Navigation is not allowed when the task is not in the foreground” is thrown and navigation is not processed correctly.

Workaround:

After restoring app from dorment/tombstone it retries navigating  if navigation has failed (yeah, quite simple solution).

It is used like that:
Image

NavigationFixService.cs – https://www.dropbox.com/s/oq0mdjg371y7vvj/NavigationFixService.cs?m

Funny difference in DP value inheritance between WP and WPF

Hi,

Have a look at the code. Try to guess

1. What color will be used to render text “Hello world” initially ?
2. Will it change after button click ?

Image

Answer:

Initially it will be yellow (yeah, it was easy). But after button click in WPF text color will change, but in SL for Windows Phone it won’t.

Explanation (actually not)

Basically i don’t understand this difference. I feel that this is a bug in Silverlight.
When we set foreground of a
1. ContentControl – the value gets inherited by TextBlockButton (TextBlockButton Foreground value is a new brush now), but notification is not sent to TextBlockButton template children (TextBlock) and TextBlock still uses old brush.
2. TextBlockButton – the notification is sent to its template children and text color changes.

Workaround:

Remove TemplateBinding for Foreground on TextBlock in ControlTemplate

Master pages for Windows Phone

Hi,

Yesterday i found a nice framework for WPF called Magellan, It adds many ultracool features to WPF. One of those won my heart. It was layouting (master pages).View Post
I’ve ported it to WP7/WP8 (unfortunately low level infrastructure differs significantly between WP Silverlight & WPF). Have a look at the resulting markup.

SmallTitledPageLayout.xaml defines quite simple layout with 200 px spacing between title and content.

Изображение

MainPage uses the layout:
Изображение

Huge thanks to http://www.paulstovell.com/ for this amazing idea and even more amazing implementation.
Here is the ported version of Layouting from Magellan to WP7: https://www.dropbox.com/s/4u0onj26yjwy8b9/Magellan.Layout.WP7.dll

Here is the ported version of Layouting from Magellan to WP8: https://www.dropbox.com/s/tqapp3ctsh5obe2/Magellan.Layout.WP8.dll