Sunday 24 November 2019

Tiered Compilation

.Net core 3.0 has come up with a huge surprise for me, Tiered Compilation (it exists since 2.1, but now it's enabled by default). Years ago I had written about how odd it seemed to me that contrary to Java HotSpot and to all modern JavaScript engines (that initially either interpret or JIT compile a method with a fast, lower-quality Jitter and then, if considered appropriate, will replace it, hot-swap, with a optimised Jitted version) .Net continued to use a single pass JIT compiler. Now things have changed.

Now .Net core comes with a fast, lower quality JIT compiler (tier-0) and with a slower, higher quality JIT compiler (tier-1). At runtime, methods are initially compiled to Native code with tier-0, and if they are executed more than 30 times, they'll get compiled again (by tier-1) and hot-swapped. This article provides some useful diagrams. Long in short, calls to compiled methods have now an additional level of indirection, where a count and jump to "initial, non-optimised native code" is done until the counter threshold is reached, then the "count and jump" is replace by a "jump to the new optimised native code". Several versions of the compiled native code get stored and over time could get hot-swapped again, but I have not found information about when this could be done.

Reading some other articles [1], [2] you'll find that .Net already had since the beginning 2 different quality JIT compilers. A faster one (equivalent to current tier-0) was used for debug builds, and an optimised one (equivalent to tier-1) for release builds. The thing is that you were stuck to one version or another, and no hot-swapping existed. There's also the question of why not using an interpreter rather than a not optimised JIT (and then the optimised JIT for frequently invoked methods), as done by Java Hot-Spot or some JavaScript engines. The main answer is that right now .Net does not have a good-enough interpreter (but it seems Mono has introduced a high-quality interpreter... so who knows if this could change in the future).

Finally, we have to take into account that .Net Core provides also Ready To Run images (R2R). This means that the compiler will compile your C# code (I guess this also exists for VB.Net and F#) to native code rather than CIL Bytecodes. This way when the application is run, the tier-0 compiler will not be used against that code, so start-up times are even faster, cause we already have the not-optimised native code, but the counting and recompiling if appropriate with the tier-1 JIT compiler still applies, so we can end up anyway with highly optimised code.

Sunday 17 November 2019

10 Years Post

It's now 10 years since I started this blog. If you read my first post, you'll see that I was not so sure I would manage to persist on it and make it one part of my life. I can say that I've succeeded. Posting here has become one part of my life, I've turned it into an obligation, sometimes I don't feel much like writing, but I force myself to do it, I force myself to continue, to focus on something. I've written some posts in some really difficult moments of my life, and when looking back it amazes me that certain month of certain year I were able to put certain things aside and focus on writing some paragraphs unrelated to that situation and that maybe no more than 10 people would ever read. It's nice when someone still manages to surprise himself in a positive way.

10 years have passed, and obviously many things have occurred. For someone moving from thirty-something to forty-something I guess I have not gone through some of the expected processes: finally finding a "life-partner", having children... Well, for an Asturian these processes are not so evident, this is probably the place on Earth with the lowest fertility rate, and I think the percentage of people my age that have not found (and many of us have never cared at all) a person to share life with is probably really, really high. It's not a surprise at all, 10 years ago I had no interest on finding "that person", and hopefully that interest has not emerged over these years (I say hopefully cause I'm quite sure this egocentric bastard would not manage to keep a steady relationship). As I said, I've gone through some bad moments, some of them pretty bad, but it has helped me to better appreciate the good moments, and better understand what makes up those moments: family, friends, places...

Not having taken those expected steps does not mean that things have been static, on the contrary, I've changed so much in these years. My political positions have turned like 160 degrees, my main interests, the things that I appreciate the most... all this has changed a real lot. Something that in 2009 was hardly an idea became a necessity, almost an obsession (in 2012-13), to live abroad for a long time. I finally made it and ended up in one country that had never appealed to me that much, France, and it has become my second identity, my second motherland... Several years there quenched my thirst for change, and for several reasons I realised that it was time to return to my primary home, that now I appreciate much more than before. I keep my strong links with France, and one could say that in a sense I've changed from being a "citizen of the world" to being a "citizen of two countries and one continent".
My musical interests have not remained static either, but after many evolutions and having broadened my taste pretty much, now I mainly favour the same styles I loved 20 years ago.
As for work, from an external perspective little has changed, but my internal attitude is now so different. I no longer dream of "doing something significant", I still enjoy learning and coding (well, sometimes at least), but regarding work all I aspire to is to get easy assignments and reduce stress.

Many people feel sad (even terrified) about getting old. I think it was the same for me in the past, but not now. It's not because I don't appreciate this life, just the contrary. As time goes by we are all aware that the end is closer, but not everyone is aware of how having reached this point in the path is an achievement. People die at any age, under any situation, so being able to look back and see how the traversed path has got longer should relieve us and make us feel fortunate, make us give thanks to whoever-whatever we think has helped us reach this point. Already quite a long time ago I said this sentence "Cada día vivido es una victoria frente a la muerte / Each day we live is a victory against death". Some friends thought of it as a very depressive conclusion, about an obsession with the idea of death stalking us I guess... but it's not like that really, or at least only partially. For me it's light coming out of darkness... We are our memories, and the more memories the more we are. The last pages of Serotonin by Houllebecq (a crazy, amazing book) quite shocked me (I read it in French, which is one of my most unexpected achievements of this decade). The main character, sank in a depression that is literally killing him, prints pictures of his life and wallpaper his room, what is intended to be his last room, with them. They say that when you're going to die you see all your life pass at high speed, this was like a low speed version that provided pleasures that the present no longer hosted. The more things you have to fill that sequence, I think the more sense you can say your life has had.

This has been a very personal post, and if you have read it to this point, most likely you are someone that is a part of my life. If that's the case, I want to say Thanks, for having been there all this time and for remaining there in the future. I plan to continue to write boring paragraphs here, and I hope we'll be lucky to share a "20 years post" in 10 years time. I also hope we'll be sharing passages of our lives face to face, in front of a coffee (or a beer for many of you) more frequently than we do. You know that I'm a socially lazy person, but I appreciate more and more those shared moments. On se voit!

Saturday 16 November 2019

Iterating multiple times

There's something in the behaviour of IEnumerables-IEnumerators created by an Iterator method in C# that is quite confusing. Let's start by the behaviour of JavaScript generators, that is the expected one for me, and let's see then the oddities of the C# version.

In JavaScript, a generator function returns a generator object, an object that is both an iterable and an iterator. So when asking it for an iterator (via [Symbol.iterator]) it returns itself. Because of this, if we try to iterate multiple times our iterable, the iteration will only happen the first time. During this first iteration the iterable-iterator object reaches its end, so next iterations will do nothing.

function* getCountries(){
 yield "France";
 yield "Belgium";
 yield "Portugal";
}

let countriesGenOb = getcountries();

let countriesIterator1 = countriesGenOb[Symbol.iterator]();
console.log(countriesGenOb === countriesIterator1 ? "same object" : "different object"); //same object


console.log("- first iteration:");
for (let country of countriesGenOb){
 console.log(city);
}

//France
//Belgium
//Portugal

console.log("-------------");

console.log("- second iteration:");
//no iteration is done, countriesGenOb[Symbol.iterator] is returning the same object
//that was already iterated to the end in the previous loop
//very interesting, this behaviour is different from C#, here the generator object (this is both iterable and iterator) is returning itself, rather than a copy
for (let country of countriesGenOb){
 console.log(city);
}

//Nothing gets printed

let countriesIterator2 = countriesGenOb[Symbol.iterator]();
let countriesIterator3 = countriesGenOb[Symbol.iterator]();
console.log(countriesGenOb === countriesIterator2 ? "Same reference" : "Different reference"); 
//same reference
console.log(countriesGenOb === countriesIterator3 ? "Same reference" : "Different reference"); 
//same reference

The behaviour in C# is different and surprising. An Iterator method returns an object that implements both IEnumerable and IEnumerator, but we can iterate it multiple times. This is like that because it seems that when we call GetEnumerator on and IEnumerable-IEnumerator that has already been enumerated, it does not return a reference to the same object, but to a new object implementing also IEnumerable and IEnumerator.

  var countries = GetCountries();
  Console.WriteLine(countries is IEnumerable); 
  //True
  Console.WriteLine(countries is IEnumerator); 
  //True

  Console.WriteLine(countries == countries.GetEnumerator() ? "Same reference" : "Different reference");
  //Same reference

  //the Iterator method is returning an IEnumerable/IEnumerator object, but the thing is that calling to GetEnumerator returns a new instance, rather than the object itself
  //Because of that the 2 loops do a whole iteration, and enumerator1 and 2 are different objects.
  Console.WriteLine("- first iteration:");
  foreach(string country in countries)
   Console.WriteLine(country);
  
  //France
  //Belgium
  //Portugal
  
  Console.WriteLine("-----------------");
  Console.WriteLine(countries == countries.GetEnumerator() ? "Same reference" : "Different reference");
  //Different reference
  
  Console.WriteLine("- second iteration:");
  foreach(string country in countries)
   Console.WriteLine(country);
  
  //France
  //Belgium
  //Portugal

  Console.WriteLine("-----------------");

  var enumerator1 = countries.GetEnumerator();

  Console.WriteLine((enumerator1 == countries) ? "Same reference" : "Different reference"); 
  //Different reference
  

  var enumerator2 = countries.GetEnumerator();
  Console.WriteLine((enumerator1 == enumerator2) ? "Same reference" : "Different reference"); 
  //Different reference


<-- CSharp and JavaScript current sources F:\Main\MyWebCreatures\deploytonenyures\SourceCode\GeneratorsIterators_IterateMultipleTimes -->

Sunday 10 November 2019

Deferred-Lazy Iterable

When in my last post I talked about how to provide lodash-like functionality to Async Iterables, I did not realise that indeed lodash (or underscore for the matter) do not work with normal Iterables. The Array methods work with arrays and the Collection methods work with Objects. Well, Iterables are objects, but if you check the source code for example for map you'll see that it checks if the object is an array (in which case it traverses it with a while-length loop) or just an Object, in which case it traverses it using Object.keys... so it won't work for non-Array iterables. The solution is converting your iterable to an Array, which in modern JavaScript is so clean as doing [...myIterable],

var _ = require('lodash');

function* citiesGeneratorFn(){
 let cities = ["Xixon", "Toulouse", "Lisbon", "Tours"];
 for (city of cities){
  yield city;
 }
}

let cities = citiesGeneratorFn();

//lodash methods do not work with iterables
console.log("with iterable");
console.log(_.map(cities, city => city.toUpperCase()).join(";"));
//nothing gets printed

//we have to convert the iterable to an array
console.log("with array");
console.log(_.map([...cities], city => city.toUpperCase()).join(";"));
//XIXON;TOULOUSE;LISBON;TOURS

Problem with this is that you are losing one of the main features of iterables, that they are deferred. First, if my generator function*: citiesGeneratorFn above were doing something like retrieving the city data via a server call, I would not need to do that retrieval until the moment when I were doing a next call to get that city, but when converting to array, we are doing all those calls in advance, even if then I'm only going to use the first city. Second, as lodash does not support iterables, all the map, filter... functions are applied to all the elements of the array, even if again we are only going to use the first one. Because of this is why a library like lazy.js (of which I talked recently) exists.

So, it came to my mind how would I go in order to try to implement something like that, a map, filter... functions that worked nicely with iterables and hence deferred. Thanks to generators it's pretty straightforward. I create an ExtendedIterable class that will wrap the original iterable. This class features map and filter methods. The important thing is that each of these methods returns a new ExtendedIterable (so I can chain the calls) that applies the function logic to the value to return, one by one, taking advantage again of generators. All in all, we have this:

class ExtendedIterable{
    constructor(iterable){
        this.iterable = iterable;
    }

    *[Symbol.iterator](){
        for (let it of this.iterable){
            yield it;
        }
    }

    map(fn){
        //I need to use the old "self" trick, cause we can not declare a generator with an arrow function
        //so as we are using a normal function, "this" is dynamic, so we have to trap it via "self"
        let self = this;
        function* _map(fn){
            for (let it of self.iterable){
                yield fn(it);
            }
        };
        let newIterable = _map(fn);
        return new ExtendedIterable(newIterable);
    }

    filter(fn){
        let self = this;
        function* _filter(fn){
            for (let it of self.iterable){
                if (fn(it))
                    yield it;
            }
        };
        let newIterable = _filter(fn);
        return new ExtendedIterable(newIterable);
    }
}

function* citiesGeneratorFn(){
 let cities = ["Xixon", "Toulouse", "Lisbon", "Tours"];
 for (city of cities){
  yield city;
 }
}
let cities = citiesGeneratorFn();

//I could just use the array, and array is iterable and the citiesGenerator is not doing any processing, just retrieving the value directly
//let cities = ["Xixon", "Toulouse", "Lisbon", "Tours"];

let extendedIterable = new ExtendedIterable(cities);

let result = extendedIterable.map(it => it.toUpperCase())
    .filter(it => it.startsWith("T"));

for (let it of result){
    console.log(it);
} 

//or just convert to array and join it
//console.log([...result].join(";"));

I've uploaded the code to a gist. This is just a POC, if you want something real, go for lazy.js.

Thursday 7 November 2019

Async Iterables

I've been playing around lately with Async Iterables (the JavaScript equivalent to C# Async Streams), and I've thought I should share it here for future reference. Same as an object is Iterable if it has a [Symbol.Iterator] method, it is asynchronously iterable if it features a [Symbol.asyncIterator] method. Both method return an object (the iterator) with a next method, that in the first case returns an object {done: bool, value: any} and in the second case a Promise of {done: bool, value: any}. Notice that in both cases the method is called next while in C# we have IEnumerator.MoveNext but IAsyncEnumerator.MoveNextAsync.

I've written some basic code where I define an Iterable class implementing the [Symbol.asyncIterator] method in 3 ways. The first and the second create the iterator "manually" (the only difference is that in one case I use Promise.then and in the other the magic of async-await. In the third case I leverage generators.

function getPost(postId){
    return new Promise((res) => {
        setTimeout(() => {
            if (postId != 4)
                res("post: " + postId + " content");
            else
                res(null);
        }, 500);
    });
}

//in all cases the iterator returned by asyncIterator returns a Promise<{done, value}>
class InfoBox1{
    [Symbol.asyncIterator]() {
        return {
            postId: 0,
            next(){ 
                return getPost(this.postId++)
     .then(post => post === null ? {done: true}: {done: false, value: post});
            }
        };
    }
}

class InfoBox2{
    [Symbol.asyncIterator]() {
        return {
            postId: 0,
            async next(){ 
                let post = await getPost(this.postId++);
                return post === null ? {done: true}
                    : {done: false, value: post};
            }
        };
    }
}


class InfoBox4{
    //"*" cause it contains "yield" statements
    //"async" cause it contains "await" statements
    async *[Symbol.asyncIterator]() {
       let postId = 0;
        while (true){
            let post = await getPost(postId++);
            if (post !== null)
                yield post;
            else 
                return;
        }
    }
}


async function asyncMain(){
    let infoBox = new InfoBox1();
    for await (let post of infoBox){
        console.log(post);
    }
    
    console.log("--------------");
    
    infoBox = new InfoBox2();
    for await (let post of infoBox){
        console.log(post);
    }

    console.log("--------------");

    infoBox = new InfoBox4();
    for await (let post of infoBox){
        console.log(post);
    }
}

asyncMain();

It's important to notice how we can declare async next(), and async *[Symbol.asyncIterator]() but bear in mind that while we can declare an arrow function async, we can not use arrow functions as generators.

It would be pretty convenient to be able to use map, filter... and similar functions with Async Iterables. There are some attempts on this, like wu.js. Well, I've come up with a different approach. We could transform the Async Iterable into an Observable, and then leverage the many rxjs operators. Transforming the Async Iterable into an Observable is as simple as this:

function asyncIterableToObservable(asyncIterable){
    return new Observable(async (observer) => {
        for await (let item of asyncIterable){
            observer.next(item);
        }
        observer.complete();
    })
}

And now you can leverage rxjs operators:

async function* citiesGeneratorFunc() {
    let cities = ["Xixon", "Toulouse", "Lisbon", "Tours"];
    for(let city of cities){
        yield await new Promise(res => {
            setTimeout(()=>res(city.toUpperCase()), 600);
        });
    }
}

let citiesGeneratorObj = citiesGeneratorFunc();
let citiesObservable = asyncIterableToObservable(citiesGeneratorObj);
citiesObservable.pipe(
 filter(it => it.startsWith("T")),
 map(it => "[" + it + "]"))
).subscribe(it => console.log(it));

//[Toulouse]
//[Tours]

Friday 1 November 2019

Lazy Split

Those working with C# should be rather familiar with the idea of performing lazy operations on collections. With linq to collections, when you chain operations (provided as extension methods by System.Linq.Enumerable) on an IEnumerable, these operations are not executed until the first time you iterate the resulting Enumerable (this is called deferred execution). Furthermore, whenever possible, the operations are performed one by one, as we retrieve each element during the iteration. For example, for the Select (equivalent to Map in other languages) or Where (equivalent to filter in other languages) methods, when we retrieve the first element, we will execute the delegate provided to Select for only one element, and the delegate provided to Where only until we obtain the first element fullfilling the condition. This is called lazy evaluation. However, a method like Sort needs to execute its delegate for all elements before retrieving the first item, this is called eager evaluation. All this is much better explained in this post.

The other day I came across lazy.js that brings this concept of deferred execution of operations on collections to the JavaScript world. Basically they have implemented the methods provided by underscore-lodash in a "lazy manner". They are all deferred, and I guess whenever possible the evaluation will be lazy rather than eager. Lazy.js is not only about collections, it also includes lazy funcionality for strings, like for example a lazy split. Honestly I'd never thought about something like this, but it makes much sense for huge strings.

Out of curiosity, I decided to implement my own lazy split, which is pretty straightforward thanks to generators:

function* lazySplit(source, separator){
 let curPos = 0;
 curPart = "";
 while (curPos < source.length){
  curPart += source[curPos];
  if ((curPart).endsWith(separator)){
   yield curPart.substring(0, curPart.length - separator.length);
   curPart = "";
  }
  curPos++;
 }
 yield curPart;
}

function doTest(str){
 console.log("- splitting: " + str);
 let generatorObj = lazySplit(str, ";");
 for (let it of generatorObj){
  console.log(it);
 }
 console.log("--------------\n");
}

doTest("a;bc;de");
doTest("a;bc;");
doTest("a;;de");
doTest(";;");

.Net lacks a lazy split in the standard library, so other people have implemented it.