Self Review. Self Review. Self Review.

I could’ve stressed more.

Peer review is nice, but self-review is awesome.

No one is more intimate with your code than you.

Keep revisiting your code after some duration, say 2-3 weeks. It’s important to give yourself some time before jumping into another session of self-review. That isolation gives you time to bring a fresh perspective but with the same intimacy.

The best case scenario is when you have the luxury of writing new code way before the release deadline. Because then you have the time to improve the code for the first release itself. But, still it’s better than not doing it at all… something’s better than nothing… better late than never.

Quite a few times it happens that I revisit my code and ask myself “Did I do that? (in third person – ) Today’s Manish would not do that. Because he knows a better way now”.

Oh BTW, each time you improve your code and stare at the beauty of the code…that feeling is awesome.

Can you do this? Folders with same name

This post is not related to coding/development per se, but it’s fine to put in some fun posts once in a while.

Can you make multiple folders of the same name at the same location?

I can…

same_folder_names_1
5 folders with the “same” name at the same location

🙂

There is no photo-shop or any other type of editing in play here.

The lazy but over-confident Software Developer; Or why we need testing

I myself am a Software Developer… but this is true for some:

why_sqa
This is why we need SQA

– Manish

Simple things I like about C++11

Note: Some of these features might not be supported by your compiler.

1)  Keyword ‘auto’ – the type comes from the initialization.

A simple example:

auto rand_rc = new std::set<UINT64>;

The compiler deduces the type of ‘rand_rc‘ as ‘std::set<UINT64>*‘.

Now take a look at this:

void printErrorsInMap( map< int, set<UINT64>* > & errorMap )
{
for (auto iter = errorMap.begin(); iter != errorMap.end(); ++iter)
{
cout << “Errors for RC #” << iter->first << endl;

}
}

Here, the type of iter is automatically deduced as map< int, set<UINT64>* >::const_iterator.
How convenient is that!!

No need to write the long types and there’s no room for any issue related to type-safety… you see, the compiler makes the best decision.

2)  nullptr
A type nullptr_t especially-created for the null pointer (of any type).

No longer the need to use that potentially un-safe NULL – which can be an int also.

With the nullptr you CANNOT say:
int invalid_type = nullptr;

3)  Static Assertion.
An assertion that happens at compile-time.

static_assert(const_expr, string); Continue reading “Simple things I like about C++11”

It’s all about Speed

When it comes to speed, everybody likes it fast. That’s why 100 m., 200m. and 4x100m. final races are the most glamorous events in Olympics – which is not to take any respect away from the long-distance runners (endurance earns respect).

And everybody loves a faster software… right?

So, as a software developer, it’s natural to think of ways to make the code more efficient and faster. Especially if the code is to run in a resource-constrained environment.

Apart from the algorithm, design and data-structure efficiency, there are a few small (language-related) things that can be done to improve the code-speed.

Before we start with the list, please note – optimization should never be the first thing on your mind… it should be the last. Once you’re sure that the code is working absolutely properly, only then start thinking about optimization.

Here we go:-

1) I don’t have a name for this one…

for (int i = 0; i < max_val; i++)
vs
for (int i = max_val – 1; i >= 0; – -i)

In the first case, to compare i with max_val, the value of max_val has to be read from the memory on each iteration.
I know some (including me) might consider it an over-kill… But I’m fond of this one. And these can matter at embedded level.

Another thing… In the second case we are using pre-increment as opposed to the post-increment. That brings me to the 2nd point.


2) If possible, always use pre-increment operator.
Prefix operator is always faster than the corresponding postfix operator.

This may not be a big thing with simple primitive types, but with bigger classes/structs, it becomes a big deal.

The post-increment operator has to keep a copy of the original to be returned.


3) temporary objects
some_class temp_heavy_func(vector<some_class> input)
{
int idx = 0;
/* do something */
return input[idx];
}

Here the first temporary is created Continue reading “It’s all about Speed”

Rules for Developing Safety Critical Code

Came across a nice paper by NASA/JPL scientist Gerard Holzmann on coding guidelines.

Fun Notes:

  • Interestingly, I recently wrote a couple of posts on the very same topics discussed in the paper – on function calls and macros – in my earlier posts. Amazing how events happen in this universe.
    🙂
  • I’ve worked on a project in which I blatantly broke the first rule – by using setjmp/longjmp to gracefully handle asserts and error-conditions.

Here’s the link to the paper The power of Ten — Rules for Developing Safety Critical Code.

Breaking and Stripping Down a Product / Project

Breaking a Product / Project

We all know that breaking down a problem into pieces is a good idea. It makes the problem approachable and manageable.

That’s what we do in real life and during software development. We break it into smaller problems and tackle each of them individually.

This process has one more added advantage… the solution to one of the smaller problems can be re-used when you break-down another big problem. That’s the idea behind functions and classes in C++ (and many other programming languages).

Other than breaking down there’s one more concept – the concept of Stripping Down.


Stripping a Product / Project

Stripping involves getting rid of all the ‘clothing’ so that the product is left to it’s bare minimum – bring it down to the basic functionality. For eg., remove all the GUI components, remove all the fancy features, study and remove everything that doesn’t affect the basic functionality.

A stripped-down version can be implemented relatively quickly than a non-stripped version. And a working stripped model gives a lot of confidence that the whole product would eventually work well – a comforting situation for the developers.

Once you have the basic model working, start putting the layers of clothing. This is a very systematic process and leaves very little room for surprises – if there’s any surprise, you would encounter it very early in the project life cycle.

Another advantage of this process – you can do a quick feasibility check: whether you are going to meet the requirements. Maybe some minimum speed requirements, or some memory constraints.
And if required, the team can take measures accordingly, before it has moved too far ahead that any changes would cost a lot.

Function calls – Speed Breakers

I recently worked on a project where my primary objective was to improve the performance of the software – increase the speed
We use Intel VTune Amplifier for profiling.

I started by first studying the code and then went on to profile it. As expected, I found many types of hot-spots. But in this post I’m going to discuss the performance hit taken due to function calls.

[ Please… I’m not advocating anything against functions… they’re great with all sorts of advantages ranging from clarity to modularity… But sometimes, they are unnecessary or sometimes their call-count can be decreased, ummm, let me explain… after all that’s the purpose of this post ]

OK, there was this function which was called around thousands to millions to 10s of millions of time depending on the input size. Lets call it high_frequency_func().

Now, high_frequency_func() itself was very well written by the original author – had very less to no scope for improvement. That made me go into a minor paralysis mode (where I just stare at something with sharp thoughts buzzing around in my mind) for a couple of seconds.

I realized that the only option to make some performance gains here was to somehow reduce the total number of times high_frequency_func() was getting called i.e. make it a “low_frequency_func()“.
[ note: high_frequency_func() is called many times for each call of the caller-function ]

Why did I think that would help? Well, read on… Continue reading “Function calls – Speed Breakers”

Should we use macros? the Good, the Bad and the Ugly

Macros are evil. -Anonymous

[mainly talking about C++]

Well, I think, as with most things, macros are sometimes good and sometimes bad. Ummm, actually, their badness outweighs their goodness.
Allow me to explain myself here:


The Good:
Convenient usage for constant values. The argument against this is that you can always use const(ant) variables. Variables would give the same result – but would use more memory.

They can be used in a  library – to return meaningful results and as keywords for configurations.

You can write a really obfuscated code (if you really need to).
It can be a bad point too. This is the most commonly exploited ‘feature’… and many a times for no good reason. I know it’s tempting, but it’s not good.


The Bad:
Not type-safe.

When used in place of functions, use up a whole lot of memory space – but would be faster than a function.

It sometimes compromises code-readability.


The Ugly:
You cannot debug the damn thing.