Never Ever...

  • Thread starter Thread starter xlar54
  • Start date Start date
xlar54 said:
I've been going through the newsgroup, picking up best practices and
things not to do, as I think it helps to make a good programmer a very
good one. But rather than fishing, I figure that there are many out
there who are tired of fixing someone else's poorly written code as it
relates to best practices, architecture, security and such. So to the
group, if you had to post a list of "never ever do this..." or "always
do this..." what would that include? We all know there's many ways to
do something, but some ways are clearly not good solutions. My
expectations here is that I will learn quite a bit as will everyone
else. Thanks for your replies.

Number one on my list of foolish things to do in any language is "a
priori" micro-optimization. By that I mean spending hours (or even
minutes) tweaking your code to "improve its speed" before you've
determined that it's slow (and what, exactly, is slow) and needs some
help. Even then, the solution is usually at a higher level: in the
design, in the choice of data structures or things like that.

Of course, it's perfectly legitimate to prefer some constructs over
others if experience has taught you that they're more efficient.

As well, there are areas of computing, and types of problems, that
require screaming tight code. Even in these areas, however, it's a
fool's game to optimize every line of code. The approach is the usual
one: create the best design you can, use the most appropriate data
structures you can, then run your program and find the trouble spots,
and optimize those.

So many people post in this newsgroup, asking whether classes or
structs are "more efficient," or stressing over the cost of boxing,
when in fact they haven't started writing their app yet. (The recent
discussion on boxing overhead excepted: the OP already had a working
app in another language and had a specific question.) So many newbies
think that the way to write good code is to torture and twist the
language to "make it fast" while at the same time they create painfully
bad designs that introduce massive overhead that code tweaking can't
begin to address.

The dumbest "optimization" I've ever seen was this (in C)... I quote it
complete with comment:

// Unwind loop to save clock cycles incrementing loop counter
int a[10];
a[0] = 1000;
a[1] = 1000;
....
a[7] = 1000;
a[8] = 1000;
a[9] = 1000;

Not only was this in the initialization phase of the program (so it
would occur exactly once per program run) but the rest of the program
then built a SQL query and headed off to a database to pull in a few
thousand rows of data. This guy shaved a few microseconds off a program
that ran for five minutes.
 
Dale said:
or, #3,

myInt = myInt + 1;

instead of:

myInt++;

or even better:

doSomethingWith(myInt++);

I avoid using increment/decrement operators within other statements
where possible. I believe the above is more clearly written (in terms
of chronology)

doSomethingWith(myInt);
myInt++;

I don't know about anyone else, but for me it requires just that little
bit less thought.
 
Bruce Wood said:
All of that said, I'm not a fan of cramming as many operations into a
line of code as possible. One of the items on my list of "never, evers"
would have to be constructs like this:

int result;
while ((result = CallSomeFunction(a, b)) > 0)
{
...
}

Blech. I'd rather repeat the function call than have to look at this,
but I recognize that that's a matter of taste.

I agree, *except* in the case of reading streams and StreamReaders. I'm
so familiar with:

int bytesRead;
while ( (bytesReader = someStream.Read(...)) > 0)
{
}

and

string line;
while ( (line = streamReader.ReadLine()) != null)
{
}

that those become simpler for me than the repeated method call.
 
Really,

I always have the idea that beside property setting this is the statement
that I use most.

for (int i;i<list.length;i++){}

Cor
 
Hi Bruce,

Good point - thanks.

--
Dave Sexton

Bruce Wood said:
Remember that after the compiler produces the IL, the JITter gets a
hold of it at runtime and transforms it into actual machine code, and
optimization takes place during the JIT compile, as well. It may be
eventually optimized out. We just now know that if it is in fact
optimized out the optimization isn't at compile time.

Given this, though, it's probably safe to say that it won't be
optimized. It looks like the kind of thing that the compiler should
deal with, not the JITter.
 
Hi Bruce,
I believe that VS2005 allows you to
see function results at the return statement, but VS2003 definitely
doesn't.

How?

That would be great, but it doesn't seem to work for me.
 
Hi Bruce,
The approach is the usual
one: create the best design you can, use the most appropriate data
structures you can, then run your program and find the trouble spots,
and optimize those.

And I'd just like to add that it's not unlikely you'll have to ditch some, or even most, of the
design and start from scratch. When designing high-performance systems it's difficult to account
for everything without prototyping first and running some tests.

--
Dave Sexton

Bruce Wood said:
I've been going through the newsgroup, picking up best practices and
things not to do, as I think it helps to make a good programmer a very
good one. But rather than fishing, I figure that there are many out
there who are tired of fixing someone else's poorly written code as it
relates to best practices, architecture, security and such. So to the
group, if you had to post a list of "never ever do this..." or "always
do this..." what would that include? We all know there's many ways to
do something, but some ways are clearly not good solutions. My
expectations here is that I will learn quite a bit as will everyone
else. Thanks for your replies.

Number one on my list of foolish things to do in any language is "a
priori" micro-optimization. By that I mean spending hours (or even
minutes) tweaking your code to "improve its speed" before you've
determined that it's slow (and what, exactly, is slow) and needs some
help. Even then, the solution is usually at a higher level: in the
design, in the choice of data structures or things like that.

Of course, it's perfectly legitimate to prefer some constructs over
others if experience has taught you that they're more efficient.

As well, there are areas of computing, and types of problems, that
require screaming tight code. Even in these areas, however, it's a
fool's game to optimize every line of code. The approach is the usual
one: create the best design you can, use the most appropriate data
structures you can, then run your program and find the trouble spots,
and optimize those.

So many people post in this newsgroup, asking whether classes or
structs are "more efficient," or stressing over the cost of boxing,
when in fact they haven't started writing their app yet. (The recent
discussion on boxing overhead excepted: the OP already had a working
app in another language and had a specific question.) So many newbies
think that the way to write good code is to torture and twist the
language to "make it fast" while at the same time they create painfully
bad designs that introduce massive overhead that code tweaking can't
begin to address.

The dumbest "optimization" I've ever seen was this (in C)... I quote it
complete with comment:

// Unwind loop to save clock cycles incrementing loop counter
int a[10];
a[0] = 1000;
a[1] = 1000;
...
a[7] = 1000;
a[8] = 1000;
a[9] = 1000;

Not only was this in the initialization phase of the program (so it
would occur exactly once per program run) but the rest of the program
then built a SQL query and headed off to a database to pull in a few
thousand rows of data. This guy shaved a few microseconds off a program
that ran for five minutes.
 
Cor Ligthert said:
I always have the idea that beside property setting this is the statement
that I use most.

for (int i;i<list.length;i++){}

Yes, I pretty much assumed that exception was a "given". In particular,
there's no interaction between the three statement-expression-list bits
of the statement.

I agree I wasn't being strictly accurate though.
 
:-) Good one. I have felt this pain recently. Another reason to just do a
very thin skeleton first and get basic things working to test your design
and shake out many things you did not think about - resist random stream of
thought and the temptation to add more function then minimal (surely we
never do that ;). The hard problems (e.g. concurrency, atomic, etc) are
much harder to see and debug with all the junk in the way. When it feels
good, then add all those nice overloads and properties and keep unit testing
along the way. Don't push a bad design and think you can "fix" it with more
code.
MS had to do this with Vista. I think over million lines of code went in
the basket. Hindsight says that was a great desision as they ended up with
a better product.
--
William Stacey [C# MVP]

| Hi Bruce,
|
| > The approach is the usual
| > one: create the best design you can, use the most appropriate data
| > structures you can, then run your program and find the trouble spots,
| > and optimize those.
|
| And I'd just like to add that it's not unlikely you'll have to ditch some,
or even most, of the
| design and start from scratch. When designing high-performance systems
it's difficult to account
| for everything without prototyping first and running some tests.
|
| --
| Dave Sexton
|
| | >
| > xlar54 wrote:
| >> I've been going through the newsgroup, picking up best practices and
| >> things not to do, as I think it helps to make a good programmer a very
| >> good one. But rather than fishing, I figure that there are many out
| >> there who are tired of fixing someone else's poorly written code as it
| >> relates to best practices, architecture, security and such. So to the
| >> group, if you had to post a list of "never ever do this..." or "always
| >> do this..." what would that include? We all know there's many ways to
| >> do something, but some ways are clearly not good solutions. My
| >> expectations here is that I will learn quite a bit as will everyone
| >> else. Thanks for your replies.
| >
| > Number one on my list of foolish things to do in any language is "a
| > priori" micro-optimization. By that I mean spending hours (or even
| > minutes) tweaking your code to "improve its speed" before you've
| > determined that it's slow (and what, exactly, is slow) and needs some
| > help. Even then, the solution is usually at a higher level: in the
| > design, in the choice of data structures or things like that.
| >
| > Of course, it's perfectly legitimate to prefer some constructs over
| > others if experience has taught you that they're more efficient.
| >
| > As well, there are areas of computing, and types of problems, that
| > require screaming tight code. Even in these areas, however, it's a
| > fool's game to optimize every line of code. The approach is the usual
| > one: create the best design you can, use the most appropriate data
| > structures you can, then run your program and find the trouble spots,
| > and optimize those.
| >
| > So many people post in this newsgroup, asking whether classes or
| > structs are "more efficient," or stressing over the cost of boxing,
| > when in fact they haven't started writing their app yet. (The recent
| > discussion on boxing overhead excepted: the OP already had a working
| > app in another language and had a specific question.) So many newbies
| > think that the way to write good code is to torture and twist the
| > language to "make it fast" while at the same time they create painfully
| > bad designs that introduce massive overhead that code tweaking can't
| > begin to address.
| >
| > The dumbest "optimization" I've ever seen was this (in C)... I quote it
| > complete with comment:
| >
| > // Unwind loop to save clock cycles incrementing loop counter
| > int a[10];
| > a[0] = 1000;
| > a[1] = 1000;
| > ...
| > a[7] = 1000;
| > a[8] = 1000;
| > a[9] = 1000;
| >
| > Not only was this in the initialization phase of the program (so it
| > would occur exactly once per program run) but the rest of the program
| > then built a SQL query and headed off to a database to pull in a few
| > thousand rows of data. This guy shaved a few microseconds off a program
| > that ran for five minutes.
| >
|
|
 
Hi William,

Don't push a bad design and think you can "fix" it with more
code.

Great advice :)
MS had to do this with Vista. I think over million lines of code went in
the basket. Hindsight says that was a great desision as they ended up with
a better product.

I read in a blog 50M lines in Vista and 24 hour builds. That's insane :|
 
Your probably closer. They still build on an IBM mainframe? I think I
remember they used to do that with NT.

--
William Stacey [C# MVP]

| Hi William,
|
| <snip>
|
| > Don't push a bad design and think you can "fix" it with more
| > code.
|
| Great advice :)
|
| > MS had to do this with Vista. I think over million lines of code went
in
| > the basket. Hindsight says that was a great desision as they ended up
with
| > a better product.
|
| I read in a blog 50M lines in Vista and 24 hour builds. That's insane :|
|
| --
| Dave Sexton
|
|
 
Hi William,

But then again, I'm not sure if they actually started from scratch at 50M. They may have dumped 1M
and ended up with 50M :)

For nightly builds do they start the day before? ;)
 
What I like about using the increment operator in the method call like I
showed is that it connects the incrementing directly to that method call - in
other words, "because I called that method, now is the time to increment the
variable."

If that statement is not true, then I may use a separate line for the
statement but in general, I don't like lines that say:

myVariable++;

Dale

--
Dale Preston
MCAD C#
MCSE, MCDBA
 
Even if the optimizer did (which according to Dave Sexton it does not)
optimize out the difference between the two forms, you should still write the
shorter version. Reading clear, concise code takes much less effort than
reading verbose code.

Dale
 
Hate's a strong word. Couldn't you just dislike them a lot? :)
--
Dale Preston
MCAD C#
MCSE, MCDBA
 
I'm with you on the optimizing thing. While we can develop coding habits
that create reasonably optimal code, beyond that source-code level
optimization should happen only when driven by performance issues.

I am a big fan of Martin Fowler's Refactoring. In it, he says something to
the effect that readable and maintainable code is almost always not the most
optimized code.

In my experience and opinion, when you compare the man-hours cost by those
optimization deficiencies compared to the man-hours it would take to optimize
and maintain the optimized code, it is always better to write readable code
than it is to write optimized code.

--
Dale Preston
MCAD C#
MCSE, MCDBA
 
Dale said:
Even if the optimizer did (which according to Dave Sexton it does not)
optimize out the difference between the two forms, you should still write the
shorter version. Reading clear, concise code takes much less effort than
reading verbose code.

On the other hand, one could easily have written that reading clear,
verbose code takes much less effort than reading short code.

It's easy to make code shorter - removing whitespace and making
variables and method names tiny does that. Making code concise in a way
which increases clarity is an art - and a subjective one at that, as
this thread has already proven.
 
Again, I agree with you, Jon. This is a case where the more concise form may
require learning more details of the language but, just as it is with
vocabulary in spoken language, more efficient communication happens with
knowledge, practice, and experience. The more you use those concise syntax
forms, the more they become part of your every day usage.

Dale
--
Dale Preston
MCAD C#
MCSE, MCDBA
 
Remeber Creative Writing 101 in college? I'm sure your instructor told you
to write your story and then go back and cut it to about 25% of the words you
started with.

The same applies to code though the percentages get better, just as in
writing, when we've learned by cutting out code so much that we write less
code that we will just have to remove later.

Dale
--
Dale Preston
MCAD C#
MCSE, MCDBA


William Stacey said:
:-) Good one. I have felt this pain recently. Another reason to just do a
very thin skeleton first and get basic things working to test your design
and shake out many things you did not think about - resist random stream of
thought and the temptation to add more function then minimal (surely we
never do that ;). The hard problems (e.g. concurrency, atomic, etc) are
much harder to see and debug with all the junk in the way. When it feels
good, then add all those nice overloads and properties and keep unit testing
along the way. Don't push a bad design and think you can "fix" it with more
code.
MS had to do this with Vista. I think over million lines of code went in
the basket. Hindsight says that was a great desision as they ended up with
a better product.
--
William Stacey [C# MVP]

| Hi Bruce,
|
| > The approach is the usual
| > one: create the best design you can, use the most appropriate data
| > structures you can, then run your program and find the trouble spots,
| > and optimize those.
|
| And I'd just like to add that it's not unlikely you'll have to ditch some,
or even most, of the
| design and start from scratch. When designing high-performance systems
it's difficult to account
| for everything without prototyping first and running some tests.
|
| --
| Dave Sexton
|
| | >
| > xlar54 wrote:
| >> I've been going through the newsgroup, picking up best practices and
| >> things not to do, as I think it helps to make a good programmer a very
| >> good one. But rather than fishing, I figure that there are many out
| >> there who are tired of fixing someone else's poorly written code as it
| >> relates to best practices, architecture, security and such. So to the
| >> group, if you had to post a list of "never ever do this..." or "always
| >> do this..." what would that include? We all know there's many ways to
| >> do something, but some ways are clearly not good solutions. My
| >> expectations here is that I will learn quite a bit as will everyone
| >> else. Thanks for your replies.
| >
| > Number one on my list of foolish things to do in any language is "a
| > priori" micro-optimization. By that I mean spending hours (or even
| > minutes) tweaking your code to "improve its speed" before you've
| > determined that it's slow (and what, exactly, is slow) and needs some
| > help. Even then, the solution is usually at a higher level: in the
| > design, in the choice of data structures or things like that.
| >
| > Of course, it's perfectly legitimate to prefer some constructs over
| > others if experience has taught you that they're more efficient.
| >
| > As well, there are areas of computing, and types of problems, that
| > require screaming tight code. Even in these areas, however, it's a
| > fool's game to optimize every line of code. The approach is the usual
| > one: create the best design you can, use the most appropriate data
| > structures you can, then run your program and find the trouble spots,
| > and optimize those.
| >
| > So many people post in this newsgroup, asking whether classes or
| > structs are "more efficient," or stressing over the cost of boxing,
| > when in fact they haven't started writing their app yet. (The recent
| > discussion on boxing overhead excepted: the OP already had a working
| > app in another language and had a specific question.) So many newbies
| > think that the way to write good code is to torture and twist the
| > language to "make it fast" while at the same time they create painfully
| > bad designs that introduce massive overhead that code tweaking can't
| > begin to address.
| >
| > The dumbest "optimization" I've ever seen was this (in C)... I quote it
| > complete with comment:
| >
| > // Unwind loop to save clock cycles incrementing loop counter
| > int a[10];
| > a[0] = 1000;
| > a[1] = 1000;
| > ...
| > a[7] = 1000;
| > a[8] = 1000;
| > a[9] = 1000;
| >
| > Not only was this in the initialization phase of the program (so it
| > would occur exactly once per program run) but the rest of the program
| > then built a SQL query and headed off to a database to pull in a few
| > thousand rows of data. This guy shaved a few microseconds off a program
| > that ran for five minutes.
| >
|
|
 
I thought we were talking about coding practices and not logic class
practices :).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Back
Top