Saturday 27 February 2021

Chisinau

Not sure how some days ago I ended up watching a non professional short video about Moldova (I'm not much into this kind of amateur, partially funny, kind of videos), the poorest country in Europe. It hardly talked about the sad facts that I'm familiar with about this failed country: massive emigration of the young locals, the maphias, the young girls exported as sex slaves, the poverty... but offered a simple approach to some basic facts.

Out of curiosity I did search in Emporis for the tallest buildings in the capital city, Chisinau (in Eastern Europe almost any interesting building built in the last century will be a high-rise). The city (and the country I guess) tops at 90 metres, and most high-rise buildings were built in the 70's and 80's when it was a Soviet Republic. Hum, massive Soviet high-rise blocks... one of those things that almost everybody hates but that I find charming, captivating and sometimes even beautiful! so I searched for some of the buildings... and I was shocked!

This is a dream!. Really, I find this high-rise "chamomile" building really amazing. If they had some money for a restoration it could really shine. Also, thanks to this piece of architectonic wisdom I've found this very interesting site about brutalism.

A google search for Chisinau Soviet Blocks brings up really mesmerizing images.

I think it's common to try to create some architectural signals at the entrance of a city. For example in Xixón (that is full of 14-16 stories "towers" from the 60's-70's) the only high-rise buildings done in the current century are in locations that mark an entry to the city. In Chisinau one of those entry points, city gates, is Portile Orasului. Wow, that is massive!

I've found this drone footage that shows some good views of the Moldovan capital.
Also, while searching about some of the buildigns I came across this excellent articleabout Soviet era architecture in Chisnau.

Sunday 14 February 2021

JITs, AOT, Caching

I already wrote in the past several posts about JIT compilers [1], [2], [3] and [4]. I've been recently reflecting about the behaviour of current JITs and runtimes.

We know that Java HotSpot and .Net Core from 3.0 will JIT compile methods frequently used over and over applying optimizations only known at runtime, replacing (hot swapping) the previous native code with a further optimized version. So with all this precious profiling optimizations done at runtime, does this optimized native code get saved to disk for being reused in the next executions?

For .NET, as far as I know, nothing like that is done, but in Java it seems it's done by means of Shared Classes Cache (these are used for sharing between multiple JVM's and can be configured to be persisted to disk).

It's interesting how this other question gives a quite different and wrong (as it would deny the existence of those shared classes) answer, but that indeed makes quite sense

The ouput of a JIT may be different for each run - it can optimize for the current load pattern. This sometimes allows it to optimize more agressively than what would be possible for pre-compiled code that needs to be reusable.

If the load-pattern changes and the optimization is found to be sub-optimal or even adverse, a JIT can de-optimize and possibly attempt a different optimization (see also About the dynamic de-optimization of HotSpot)

Now, it might sometimes save some performance to keep these results of various compiled versions around and reuse them later, but it would also require a significant amount of book-keeping to be able to find out if a section of code has already been compiled with currently relevant optimizations.

I suppose that is just not considered worth the effort. Its a tradeoff between doing file-IO and usually fast compilation of small sections of code.

Trying to apply the above wisdom to the existence of a Class Cache, one could think that maybe what is saved in the Class Cache is the first native code produced by the JIT, without any particular optimizations. The optimized code that is hot swapped as the application runs and that can contain optimizations based on the current data set would not be saved to the class cache. What would make sense for me is saving to the Class Cache some profiling information, so that in future executions it can be compared with the current profile information, to see if all executions work with similar environments.

If what I say above is correct, one could wonder why not to use AOT compilation rather than the class cache (and then at runtime continue to use additional JIT compilations for hot methods to apply optimizations. There are good discussions about the pros and cons of AOT vs JIT, like this. One interesting point brought up there and that I had never considered before, is that with JIT you are only compiling the parts of your applications that are really executed, while with AOT you compile the whole application. For a large application in which your use cases are restricted to just a small part of the application, doing AOT would involved wasting a lot of processing time.

In the JavaScript world I know that V8 has 2 JIT's, not optimized and optimized. Hot code is JITted again by the optimized JIT. I'm not sure if this optimized JIT is ran additional times for "very hot" code, performing additional how swappings, I guess so. Anyway, what I've learnt here that V8 saves to disk the compiled code to speed up further executions. My understanding is that this is done only for the code generated by the not-optimized JIT.

Before finishing this post I have to mention the very interesting approach used in modern Android (ART since Android 8), where interpreter, JIT and AOT compilation are used. From the documentation:

ART uses ahead-of-time (AOT) compilation, and starting in Android 7.0 (Nougat or N), it uses a hybrid combination of AOT, just-in-time (JIT) compilation, and profile-guided compilation. The combination of all these compilation modes is configurable and will be discussed in this section. As an example, Pixel devices are configured with the following compilation flow:

An application is initially installed without any AOT compilation. The first few times the application runs, it will be interpreted, and methods frequently executed will be JIT compiled.
When the device is idle and charging, a compilation daemon runs to AOT-compile frequently used code based on a profile generated during the first runs.
The next restart of an application will use the profile-guided code and avoid doing JIT compilation at runtime for methods already compiled. Methods that get JIT-compiled during the new runs will be added to the profile, which will then be picked up by the compilation daemon.

The backgroud AOT compilation for only frequently used code (rather than the whole application) is very interesting. I don't know if the "profile generated" contains only information about which methods are frequently run or if it contains additional generic profiling information that the AOT could use to optimize those methods. I guess Android's JIT can do hot swapping, if so, it could make sense that the AOT code could be hot swapped by code generated by the JIT based on the current execution especifities. I think this could be the case, cause I read somewhere about de-optimizations.

Sunday 7 February 2021

Ternary Operator, Expressions and Statements

Lately I've seen myself trying to overuse the ternary operator, and I've needed to review how it really works. It had made me to revisit some basic concepts like statement vs expression. In this article, if I don't specify the language it means that it applies both to C# and JavaScript. Let's see:

Expression vs Statement:
An expression returns a value.
A statement does something.
An expression followed by a ";" becomes a statement (an expression statement). But depending on the language this is not valid for all expressions.

This article is an excellent reference about expressions/statements in JavaScript. Particularly interesting sentence:

wherever JavaScript expects a statement, you can also write an expression. Such a statement is called an expression statement. The reverse does not hold: you cannot write a statement where JavaScript expects an expression. For example, an if statement cannot become the argument of a function.

An assignment does 2 things: the assignment itself and returning the assigned value. This means that you can write code like this: myFunction(a + 1);.

In JavasScript a function always returns a value. If it has no an explicit return, it returns "undefined" (that is considered as a value). This means that it's syntactically correct to use any kind of function call wherever an expression is expected. This is not the same in C#, where void is not a value.

The ternary operator is an expression made up of 3 expressions: condition, consequent and alternative. In JavaScript you can use it as a statement, and based on my precedent paragraphs, you can use as consequent and alternative code that does not look much like a expression, but indeed is treated as such. The below is perfectly valid JavaScript code (though as I explain at the end of this post, we should avoid it)


let condition = true;
let a;

condition
    ? a = "Y"
    : a = "Z";

console.log("a: " + a);

condition  
    ? console.log("True")
    : console.log("False");

The equivalent C# code will not compile. In C# the ternary operator can not be used as a statement. To make it work you'll need to use it in an assignment (even if you don't want to use the assigned value for anything).



static void ReturnNothing(string st)
{
    Console.WriteLine("inside ReturnNothing");
}

public static void Main()
{
	var a = "";
	//compiles OK, we do the assignment and pass x over
	ReturnNothing(a = "X");

	var condition = true;

	//does not compile, we can't use the ternary operator as a statement
	// condition
	//     ? a = "Y"
	//     : a = "Z";

	//we have to use this additional, useles assignment to make it compile
	var st = condition
	? a = "Y"
	: a = "Z";

	//does not compile
	// condition  
	//     ? Console.WriteLine("True")
	//     : Console.WriteLine("False");
	
}

This question explains what you can see in the code above. Though you can compile the central code, you should avoid it, as wisely explained by Eric Lippert

In my opinion, expressions should be useful for their values, and statements should be useful for their side effects. What you are running into is that you have an expression that is only useful for its side effect, and that is a bad code smell.