Category Archives: Stories

On strings, methods, return variables and IL code

Some days ago reviewing some old code I found out that a method was performing an operation with a string passed by arguments, storing the result in the same variable, and returning it at the end.

It looked weird, so I wanted to know what was really happening, and to check if there is really any difference between smashing the variable sent by argument, creating a new variable or directly returning the call result.

For that reason, I’ve created a small sample project, and later, using ILDasm, saw what was really under the hood. ILDasm is a disasembler for the Intermediate Language created by the CLR when we compile C#.

Just before we start, some quick notes:

  • IL looks like some sort of assembly-like language, in the way that it works with a call stack,  and the result of a function call is stored on the stack before returning.
  • The values are index based, so when we are executing ldarg.0, we really are operating with the value located in the index 0
  • The result of calls to external methods is also saved on the stack.
  • The IL is not the bytecode that will execute, this code is interpreted at runtime by .NET, so the final code result may be sightly different.

And here is the code!

class Program
{
    public static string MyFirstCustomFunction(string a)
    {
        a = a.Substring(4);
        return a;
    }

    public static string MySecondCustomFunction(string b)
    {
        return b.Substring(4);
    }

    public static string MyThirdCustomFunction(string c)
    {
        var result = c.Substring(4);
        return result;
    }

    static void Main(string[] args)
    {
        Console.WriteLine(MyFirstCustomFunction("Lorem ipsum dolor sit amet"));
        Console.WriteLine(MySecondCustomFunction("Lorem ipsum dolor sit amet"));
        Console.WriteLine(MyThirdCustomFunction("Lorem ipsum dolor sit amet"));
    }
}

Let’s start with the first method, if we launch ILdasm from the VS command promt, and we load the executable generated (located in /bin/Debug from our project folder), we will get this image:

ildasm

Here we can see the IL for the first method:

.method public hidebysig static string  MyFirstCustomFunction(string a) cil managed
{
// Code size       16 (0x10)
.maxstack  2
.locals init ([0] string CS$1$0000)
IL_0000:  nop
IL_0001:  ldarg.0
IL_0002:  ldc.i4.4
IL_0003:  callvirt   instance string [mscorlib]System.String::Substring(int32)
IL_0008:  starg.s    a
IL_000a:  ldarg.0
IL_000b:  stloc.0
IL_000c:  br.s       IL_000e
IL_000e:  ldloc.0
IL_000f:  ret
} // end of method Program::MyFirstCustomFunction

What we are watching can be resumed in the following points:

  • At the beginning we define a variable that matches the return type specified in the header. This variable, placed on the 0 position, will contain the return  of the method.
  • Afterwards, we load the arguments in the stack, in this case a single argument.
  • Before calling the substring function we must load into stack the other argument, a 4 byte integer of value 4.
  • Then we call the substring method, specifying both the assembly and the full namespace that contains the String class. The result of that call will be stored back into the stack.
  • After the call we retrieve the stack value and we place it back into the argument variable, replacing the existing object.
  • We read again the value from the argument to the stack and we store in the local variable 0, the return variable.
  • Finally, before returning the function, we place the return variable value on the stack, so it can be accesed from the caller method.

There are some calls like the br and the nop, that are related to how, in debug mode, extra instructions are added to the program for better step-by-step debugging, and there is a discussion on Stack Overflow about the subject, that is linked at the end of the article.

As we can see here, we are loading and storing the same value repeated times, and that may not be necesary at all.

Let’s jump into the second method:

.method public hidebysig static string  MySecondCustomFunction(string b) cil managed
{
// Code size       13 (0xd)
.maxstack  2
.locals init ([0] string CS$1$0000)
IL_0000:  nop
IL_0001:  ldarg.0
IL_0002:  ldc.i4.4
IL_0003:  callvirt   instance string [mscorlib]System.String::Substring(int32)
IL_0008:  stloc.0
IL_0009:  br.s       IL_000b
IL_000b:  ldloc.0
IL_000c:  ret
} // end of method Program::MySecondCustomFunction

As we can see It begins in the same way, but after calling the substring method the result of the method call is stored from the stack to the result variable, with no extra copying and no information smashing.

This looks like a more efficient way of working, because we save an extra Read/Write operation.

Let’s see what happens in the last case, using a extra variable defined inside the scope of the function, what would happen?

.method public hidebysig static string  MyThirdCustomFunction(string c) cil managed
{
// Code size       15 (0xf)
.maxstack  2
.locals init ([0] string result,
[1] string CS$1$0000)
IL_0000:  nop
IL_0001:  ldarg.0
IL_0002:  ldc.i4.4
IL_0003:  callvirt   instance string [mscorlib]System.String::Substring(int32)
IL_0008:  stloc.0
IL_0009:  ldloc.0
IL_000a:  stloc.1
IL_000b:  br.s       IL_000d
IL_000d:  ldloc.1
IL_000e:  ret
} // end of method Program::MyThirdCustomFunction

The first notable difference is in the local variable definition, that defines a second string variable that will hold our intermediate value.

The main difference between here and the first function is that no extra calls to the arguments are done, but, as we are saving the result in a variable before returning it, we have the same double Read/Write problem from the first case.

To sum up, if we directly return the result of a function instead of assigning it to a variable, we will avoid double Read/Write. The third option, while looks interesting, defines another variable, and more memory allocation.

Further reading

Edit:

Firefox OS: First steps

Ver este artículo en castellano aquí

On march 20th I had the oportunity to attend the “Firefox OS App Days” here in Valladolid. The goal was simple, two hours of introductory sessions and a hackathon for having a first-hand contact with the platform.

The Platform

Firefox OS is, at a glance, an Android a linux kernel similar to Android’s core + a web browser, so everything in there, including the start screen and the notifications are rendered in HTML5, so there are no “native apps”. The main difference between this approach and running an app inside an Android or iPhone browser, is that Firefox OS apps will have access to the phone APIs, including, but not limited to, contacts, calendar and other options.

Development: Tools, languages, and the simulator

We can develop a Firefox OS app in the same way we create a web app, with HTML + CSS + Javascript. This means that we can also extend our code using LESS, SASS, jQuery, Sencha, and every javascript framework we want (for my app I used Knockout.js). We only need a Firefox browser for debugging, as the rendering engine that runs on the phone is the same that runs on the browser.

Eventually we will need to test things like the camera, the contacts, notifications, or other API functions that are not available in the standard browser. For these scenarios we can use the simulator, which can be installed as a Firefox extension.

Building blocks: Native interface

As I told early, there are no “native” apps on Firefox, this means that we can use the same styles and elements for lists, buttons, headers and dialogs of the operating system for our own applications, so it integrates seamlessly. Today we don’t have a base app template, so we need to manually copy the CSS files from the Gaia repository (see links at the end of the article) to our app.

My first app

After the introduction we had a hackathon, less than two hours for having a functional app up and running. My first project is a ToDo list, with the following features:

  • The styles are made with the Building blocks, from the Gaia repository. Gaia is the name of the UI for Firefox OS.
  • The animations are made with standard CSS3 transforms and some JS, thanks to the guys of Mozilla and Telefonica I+D for the help.
  • The list is handled with Knockout.js, making it simple to draw a list without manually injecting HTML inside the DOM.

The result is what you see here:

newTask mainWindow

Next steps

This is a Hello World, of course, for this app to be fully functional I would need to save the data, and extend it using the calendar for setting alarms (for example). It may not be the first platform in the future, nor the second or the third, but I think is worth to learn a bit about it.

Links

DVCS: The ultimate tool for a hackathon

A hackathon is a social event for programmers and designers with a clear goal: Develop an app in a specific time (normally 24-72h) in the language or platform chosen by the host. Time is a key factor, and 5 minutes can turn a stable project into a complete mess.

In this case is very useful to have a version control system to track the changes done in a project, keeping those changes under control.

Last time I went to a hackathon, I saw the frustration of some of my teammates, who were using the new Team Foundation Services Preview, a great tool with a huge potential, but maybe not the best option for this scenario:

  • It needs a stable Internet connection; otherwise the checkin and checkout operations are unavailable.
  • It’s centralized, so every time a check-in is done, all the source code its integrated, so if the client detects changes in the servers, It will be necessary to get the last revision, make a local merge, and afterwards, commit the changes back to the server, wasting time.

With this in mind the version control system becomes a sync tool, rather than a control tool. This scenario, using a distributed version control system (DVCS) could be performed this way:

  • A member of the team is able to commit the changes of his code independently, in a separate branch, and keep the history of the changes.
  • The rest of the members can replicate the changes, using the local network, saving bandwidth and avoiding the usage of external servers.
  • The access may be limited, even in the same network only authorized users may be able to see the code and replicate the changes.
  • The merge operations are less frequent, integrating finished components; therefore we avoid risks like introducing new bugs. Also, tools like PlasticSCM’s Xmerge can detect refactored code helping a simpler integration.
  • All changes may be integrated at the same time the code is being created, independently.

Plastic SCM, as stated before, is a distributed SCM that allows all the discussed features, but also Git or Mercurial will do the job.

In an agile development, the right tool can make the difference between a standard app, and a winner app. On your next hackathon, try a DVCS, and if you try Plastic SCM, leave a comment with your feedback.

Hello world!

Welcome to the first entry of my english blog. 3 years after starting to blog in spanish, I thought that it could be a good idea to start translating some articles, and have this site for english readers.