Learn Something New Every Day...

Recently I started jotting down anything new that made me say "oh cool!". Some are rarely used C# language features, some are API mechanics, and some are just random trivia. Here's what I've come up with so far:

C#'s stackalloc Keyword

stackalloc is basically handy way to allocate an array on the stack and can provide several conveniences.

Instead of allocating a locally scoped array (which is backed by the heap and managed by the garbage collector), you can get better "bare metal" performance by using stackalloc:

float SomeFunction(float[] input)
{
float dataResults;
float[] data = new float[3];
// we are calculating a result from input and storing interim results in data
return dataResults;
}

At the end of this method, a float array is sitting around waiting to be garbage collected. Instead, that function can become:

unsafe float SomeFunction(float[] input)
{
float dataResults;
float* data = stackalloc float[3];
// do something with the data and input
return dataResults;
}

In addition to taking the garbage collector and heap allocation out of the equation to eek out a little more performance, you also get a native float pointer. This can make interop with unmanaged code quite friendly, rather than a giant mess of fixed statements that would come about as a result of using float arrays.

 

C#'s ?? operator

Consider the following method:

Foo EnsureNotNull(Foo foo)
{
if (foo != null)
return foo;
return new Foo();
}

You can trim that down a bit by using a ternary operator:

Foo EnsureNotNull(Foo foo)
{
return foo == null ? new Foo() : foo;
}

But why use that when ?? is a binary null check operator; I.e., it returns the left if it is not null and the right otherwise:

Foo EnsureNotNull(Foo foo)
{
return foo ?? new Foo();
}

 

Hardware Graphics Acceleration and Asynchronous Calls

This is a tip I learned way back in my hay day of amateur game development. Many OpenGL/Direct3D may be just asynchronous calls on the hardware, and subsequent operations may end up resulting in them waiting for the previous operation to finish. The following is a very common pattern in drawing routines:

void OnPaint()
{
glClear(GL_COLOR_BUFFER_BIT);
// paint a bunch of stuff
// glDrawStuff();
glSwapBuffers();
}

Here, the code is immediately making paint operations following the clear. This results in those operations waiting until the clear has completed before executing. Restructuring the code as follows can squeeze out a little more performance:

void OnPaint()
{
// paint a bunch of stuff
// glDrawStuff();
glSwapBuffers();
// clear the buffer after the background and foreground are swapped
// this clear will take place asynchronously and be complete
// when we start to draw the next frame!
glClear(GL_COLOR_BUFFER_BIT);
}

I implemented this in GLMaps recently, and saw an FPS increase from 49 to 51. That's a ~4% increase! Using this technique, any static preprocessing/setup can actually just be run at the end of the drawing operations, rather than at the beginning. (Concurrently using the CPU and GPU between frames to get a net gain in FPS)

 

Handy C# 3.0 Shorthand

This tip didn't actually catch me by surprise, since I read through the C# 3.0 new features. However, old habits die hard, so I often forget to use them. Prior to C# 3.0, the following would be a standard class declaration:

class Foo
{
int myBar;
public int Bar
{
get
{
return myBar;
}
set
{
myBar = value;
}
}

double myMoo;
public double Moo
{
get
{
return myMoo;
}
private set
{
myMoo = value;
}
}

float myCool;
private float Cool
{
get
{
return myCool;
}
set
{
myCool = value;
}
}
}

With C# class declaration shorthand, developers can now eliminate much of the redundancy (the properties and backing fields are implicitly defined):

class Foo
{
public int Bar
{
get;
set;
}

public double Moo
{
get;
private set;
}

public float Cool
{
get;
set;
}
}

Also, when declaring an instance of that class, prior to C# 3.0, a common pattern is to set some initial properties:

void MakeFoo()
{
Foo foo = new Foo();
foo.Bar = 0;
foo.Cool = 0;
}

With C# 3.0, you get additional shorthand (less characters, not lines), and a more aesthetically pleasing syntax:

void MakeFoo()
{
Foo foo = new Foo()
{
Bar = 0,
Cool = 0
};
}

 

That's it for tips for now. Share 'em if you got 'em!

10 comments:

Bobris said...

Nitpicking:
?: operator is ternary and ?? operator is binary and not unary as you written.
(remove this if you fix it)

Koush said...

Oh, thanks! I had a feeling I was wrong about that. Admittedly, I'm pretty bad with terminology at times. I spent years calling outdated APIs depreciated (loss of value over time) instead of deprecated. Hahaha...

I'll update the post. :)

SanderD said...

Koushik,

I stumbled upon a link, posted by 'RobIII' of tweakers.net. It contains various 'hidden' features of C#.

http://stackoverflow.com/questions/9033

On a sidenote, I really enjoy your blog posts! Thank you for that.

Hope it's useful,
SanderD

Anonymous said...

i kill dragon today, what you kill? nothing!

Gareth said...

I had similar thoughts about learning new things earlier this month, specifically regarding the usage of the [Flags] Attribute on enumerated types.

Can't see myself using stackalloc much, but ?? could be pretty useful. Thanks!

Amgad said...

I didn't have the time yet to read about the new stuff in C# 3. I liked the Handy C# 3.0 Shorthand section.

Mikko Ohtamaa said...

Hi,

Is it ok to subscribe your blog to planetmobile.us aggregator?

Can you please reply to mikko (at) redinnovation dot com

Scott Mitting said...

Oooh. I love the ?? operator. Consider this code:

public Thing MyObject
{
get { return myobject ?? (myobject = new Thing(); }
}
private Thing myobject = null;



Another cool concept I learned from Unity3D is the concept of using IEnumerable as a way to do coroutines (cooperative multithreading).

Here's their documentation

Andres said...

Another timesaver is the collection initializer:

Instead of writing:

var ints = new List<int>();
ints.Add(1);
ints.Add(2);

you can now write:

var ints = new List<int> {1, 2};

That's pretty sweet.

Adam said...

Something else you might not know about shorthand C# properties is get and set can have different access levels:

public int Property { get; private set; }