I have often used those three terms almost interchangeably,
yes, even computer scientist. After all, most of us have a degree in computer
science, so what does that make us? However, recently I find that those three
things have come to take on more and more distinct personalities in my mind. It
has come to the point where if I think about someone I know – or know of –
within the industry, they immediately fall into one of those three categories.
Which is not to say that one person can't have attributes from all three, but
regardless, they always tend to favor one most strongly and so I fit them into
that category, programmer, developer or computer scientist.
It is difficult to define what each one should be, (it is
more of a gut feel rather than a strict delineation) they are very similar
(and rightly so), but I am going to attempt to do it anyway, cause I am
a glutton for punishment :).
The terms are different, and they refer to differing expectations.
Usually, "Software Engineer" is a super-set of
"Programmer".
Programming computers is PART of Software Engineering; but
it's by far not all of it.
Coding Standards
Developers always love to fight about coding standards. But it is very vital to follow coding standards to achieve consistency throughout the project or code. All should be of the same mind that conventions are very influential. I will show some good practices that I have learned during my professional years, those are lower level but very important for all levels.
Question: Probably, the basic
situation is familiar to everyone. You have agreed on certain coding standards
in your team and now it is time to make sure that everybody follows them.
Some do it via heavy paired programming,
others maintain a list of coding standards and do a manual review. Others even
use the static code analysis tool from Visual Studio to make sure that coding
standards are enforced.
What are your best practices to ensure coding
standards? Which tools do you use - are there some essential tools every dev
should know? How do you integrate the standardization of your code in your
development tools?
Answer: First, make sure you have a proper
build server that continuously builds your code. TFS or Jenkins/Hudson+Msbuild
are good options. On this build server you of course run tests, and you can
also run static code analysis as well as syntax checkers.
One important key to success: don't deploy
them with a massive rule-set and expect it to work well. You will have millions
of warnings and no one will care.
Rules of thumb are:
Always have zero warnings. Reduce the set of
checks initially if you have to, then add some new checks every sprint and fix
those. Make sure every check performed has actual value to you and is
consistent with your standards.
If you have domain specific rules you need to
adhere to, don't be afraid to implement your own rules.
For syntax check, use StyleCop or StyleCop
for Resharper if you are using Resharper (which I highly recommend as well).
StyleCop (now also StyleCop for Resharper) is
commonly used to enforce coding style rules within C# code bases.
It can be integrated into your CI build and
cause build failures if any violations have been introduced.
Best Practices for Writing High
Performance Code
With faster processors and memory being
almost free programmers are increasingly tempted to program for convenience and
not performance. I recently had to write an application where performance was
paramount and here are my tips for writing high
performance C# code:
1.Avoid boxing and unboxing
Boxing/unboxing enables value types to be treated as objects which is stored on the garbage collected heap. Boxing is the packaging of the value type in an instance of the object reference type and unboxing is the extraction of the value type from the reference type. Where possible this should be avoided as it is a major drain on performance.
EG:
Boxing/unboxing enables value types to be treated as objects which is stored on the garbage collected heap. Boxing is the packaging of the value type in an instance of the object reference type and unboxing is the extraction of the value type from the reference type. Where possible this should be avoided as it is a major drain on performance.
EG:
int i = 999;
object oObj = (object)i; // boxing
…
oObj= 999;
i = (int)oObj; // unboxing
object oObj = (object)i; // boxing
…
oObj= 999;
i = (int)oObj; // unboxing
2.Avoid Finalize
The .NET garbage collector automatically handles the disposable of unused items, using Finalize the explicitly destroy an object requires invoking an instance of the garbage collector which is un-necessary and is a drain on performance.
The .NET garbage collector automatically handles the disposable of unused items, using Finalize the explicitly destroy an object requires invoking an instance of the garbage collector which is un-necessary and is a drain on performance.
3.Read Values From Objects Only
Once
Reading values from objects is not as fast as assessing the value of a simple variable. For example, a loop through an array’s contents should not access the array’s Length property on each iteration of the loop, instead copy the Length property to an Integer and then access this value on each iteration.
This applies to any classes you create as well, read all properties into a simple string or integer type if possible and then access that type multiple times.
Reading values from objects is not as fast as assessing the value of a simple variable. For example, a loop through an array’s contents should not access the array’s Length property on each iteration of the loop, instead copy the Length property to an Integer and then access this value on each iteration.
This applies to any classes you create as well, read all properties into a simple string or integer type if possible and then access that type multiple times.
4.Use The StringBuilder – Wisely!
Concatenating large strings in a loop is a performance drain and the Stringbuilder’s Append method is much more efficient. However don’t go overboard on this, the Stringbuilder is object requires a lot more memory than a String and it is not efficient for concatenating a small number of times – only use the Stringbuilder if more than four concatenations are required.
Concatenating large strings in a loop is a performance drain and the Stringbuilder’s Append method is much more efficient. However don’t go overboard on this, the Stringbuilder is object requires a lot more memory than a String and it is not efficient for concatenating a small number of times – only use the Stringbuilder if more than four concatenations are required.
5.Minimize Exceptions
Catching and throwing exceptions is very expensive and should be avoided where possible. Exception blocks should never be used to catch an error caused by attempting to access a null object, instead use an statement to test if the object is null before accessing it:
if (myObj != null)
{
//perform operation
}
else
{
//catch error
}
Catching and throwing exceptions is very expensive and should be avoided where possible. Exception blocks should never be used to catch an error caused by attempting to access a null object, instead use an statement to test if the object is null before accessing it:
if (myObj != null)
{
//perform operation
}
else
{
//catch error
}
6.For Instead of ForEach
ForEach can simplify the code in a For loop but it is a heavy object and is slower than a loop written using For.
ForEach can simplify the code in a For loop but it is a heavy object and is slower than a loop written using For.
7. Use Sealed Classes
Classes that do not need to be inherited from should be marked as sealed. Sealed classed remove the inheritance features of a class and allows the .NET framework to make several run-time optimizations.
Classes that do not need to be inherited from should be marked as sealed. Sealed classed remove the inheritance features of a class and allows the .NET framework to make several run-time optimizations.
8.Thread Pooling
Initializing threads is expensive so if your code uses thread, avail of .NET’s thread pooling:
Initializing threads is expensive so if your code uses thread, avail of .NET’s thread pooling:
WaitCallback methodTarget = new WaitCallback(
myClass.UpdateCache );
ThreadPool.QueueUserWorkItem( methodTarget );
ThreadPool.QueueUserWorkItem( methodTarget );
When QueueUserWorkItem is called, the method
is queued and the
calling thread returns and continues execution. The ThreadPool class uses a thread
from the application’s pool to execute the method passed in the callback as soon as
a thread is available.
calling thread returns and continues execution. The ThreadPool class uses a thread
from the application’s pool to execute the method passed in the callback as soon as
a thread is available.
9.Collections
Where possible use arrays instead of collections. Arrays are normally more efficient especially for value types. Also, initialize collections to their required size when possible.
Where possible use arrays instead of collections. Arrays are normally more efficient especially for value types. Also, initialize collections to their required size when possible.
10.Use Strongly Typed Arrays
Strongly typed arrays avoids the type conversion or boxing associated with using object arrays to store types.
Strongly typed arrays avoids the type conversion or boxing associated with using object arrays to store types.
Object[] array = new Object[10]
arr[0] = 2+3; //boxing occurs here
arr[0] = 2+3; //boxing occurs here
Avoid the boxing overhead by declaring a
strongly typed array:
int [] arrIn = new int [10];
arrIn[0] = 2+3;
arrIn[0] = 2+3;
These are just my tips, please let us know if
you have any of your own.
11. File
Organization : C♯ Sourcefiles Keep your classes/files short, don't exceed
2000 LOC, divide your code up, make structures clearer. Put every class in a
separate file and name the file like the class name (with .cs as extension of
course). This convention makes things much easier.
12 Directory Layout:
Create a directory for every namespace. (For MyProject.TestSuite.TestTier use
MyProject/ TestSuite/TestTier as the path, do not use the namespace name with
dots.) This makes it easier to map namespaces to the directory layout.
Quick Test
Let us demonstrate a FizzBuzz example. The
FizzBuzz test is to write a program that
goes through the numbers 1 to 100. For every multiple of 3, the program should
output "Fizz" and for every multiple of 5 it should output
"Buzz". If both above conditions are met it should output
"FizzBuzz". If none of the above conditions are met, it should just
output the number.
Example 1:
public void Test()
{
for (int i = 1; i < 101; i++)
{
if (i % 3 == 0 && i % 5 == 0)
{
Console.WriteLine("FizzBuzz");
}
else if (i % 3 == 0)
{
Console.WriteLine("Fizz");
}
else if (i % 5 == 0)
{
Console.WriteLine("Buzz");
}
else
{
Console.WriteLine(i);
}
}
}
What do you think? Do we need to make the
code better?
Example 2:
public void Check()
{
for (int i = 1; i <= 100; i++)
{
string output = "";
if (i % 3 == 0) { output = "Fizz"; }
if (i % 5 == 0) { output = output + "Buzz"; }
if (output == "") { output =
i.ToString(); }
Console.WriteLine(output);
}
}
What do you think now? Do we need to make the code even
better?
Ok, let me help to make it better. Naming thing is one of
the hardest job we have as a software developer. Because we spend a lot of time
naming things, there are so many things to name properties, methods, classes,
files, projects etc. We should spend some energies for naming things because
names can be meanings. Adding meaning to code is readability all about.
public void DoFizzBuzz()
{
for (int number = 1; number <= 100; number++)
{
var output = GetFizzBuzzOutput(number);
Console.WriteLine(output);
}
}
private static string
GetFizzBuzzOutput(int number)
{
string output = string.Empty;
if (number%3 == 0)
{
output = "Fizz";
}
if (number%5 == 0)
{
output += "Buzz";
}
if(string.IsNullOrEmpty(output))
{
output = number.ToString();
}
return output;
}
What do you think now? Is this better than previous examples?
Is it more readable?
What is better Code?
Write code for People First, Computers
Second. Readable code doesn't take any longer to write than confusing code
does, at least not in the long run. It’s easier to be sure your code works, if
you can easily read what you wrote. That should be a sufficient reason to write
readable code. But code is also read during reviews. Code is read when you or
someone else fixes an error. Code is read when the code is modified. Code is
read when someone tries to use part of your code in a similar project or
different project but similar feature or part of a feature.
“ What if you just writing code
for yourself ? Why should you make it readable? ”
Ok, the major reason behind writing readable
is , a week or two from now you’re going to be working on another project. What
will happen when any other HUMAN needs to fix an error on that project? I can
guarantee you that you will also lost within your own horror code.
From my point of view a better should carried
out the following characteristics:
Code that is easy to write , modify and
extend
Code that is clean and talks/convey
meaning
Code that has values and cares about
quality
So, write with the human reader in mind while
satisfying the needs of the machine to the degree necessary.
How can you improve the
Readability?
First you have to read other people’s code
and figure out what is good and what is bad within that code. What makes you
easy to understand and what makes you feel more complicated. Then apply those
things to your own code. Finally you need sometime, some experience and you need
some practice to improve the readability of your code. It is very hard but
obvious to implement standards in any software company, through methods like
Trainings, Peer Code Reviews, Introducing automated code review tools, etc. The
most popular tools are as follows:
FxCop is a tool that performs static code analysis of .NET code. It
provides hundreds of rules that perform various types of analysis.
StyleCop is an open source project that analyzes C# source code to
enforce a set of style and consistency rules. It can be run from inside of
Visual Studio or integrated into an MSBuild project. StyleCop has also been
integrated into many third-party development tools.
JetBrains ReSharper is a renowned productivity tool that makes Microsoft
Visual Studio a much better IDE. Thousands of .NET developers worldwide wonder
how they’ve ever lived without ReSharper’s code inspections, automated code
refactoring, blazing fast navigation, and coding assistance.
What are Conventions?
According to Wikipedia "Coding conventions are a set of guidelines for
a specific programming language that recommend programming style, practices and
methods
for each aspect of a piece program written in this language. These conventions
usually cover file organization, indentation, comments, declarations,
statements, white space, naming conventions, programming practices, programming
principles, programming rules of thumb, architectural best practices, etc.
These are guidelines for software structural quality. Software programmers are
highly recommended to follow these guidelines to help improve the readability
of their source code and make software maintenance easier. Coding conventions
are only applicable to the human maintainers and peer reviewers of a software
project. Conventions may be formalized in a documented set of rules that an
entire team or company follows, or may be as informal as the habitual coding
practices of an individual. Coding conventions are not enforced by compilers.
As a result, not following some or all of the rules has no impact on the
executable programs created from the source code."
You should be able to tell the difference
between a properties, local variable, and method name, class name etc. because
they use different capitalization conventions. These type of conventions has
values. You will be able to get lots of guidelines and conventions over
internet. So find a convention or build your own and stick with it.
The source of the following (Design Guidelines for Developing Class Libraries) was
developed by the Microsoft special interest group. I just made some addons.
No comments:
Post a Comment