c# interview question

G

Guest

Hi,

I recently had an interview where I was asked a number of questions on C#.
Unfortunately I didn't get the answers from the test and find that one of
them is still niggling me.

It was something like this:

Consider the following code:

int i = 0;
Console.WriteLine("The value is: " + i);
Console.WriteLine("The value is: " + i.ToString());

Which would you use to write an integer to the console and why would it give
better performance?

I said I would use: Console.WriteLine("The value is: " +
i.ToString());

But I can't think why this should give a performance advantage. I can only
guess that the compiler should be able to realise that a string is required
from the integer for the line not using the ToString() method and generate
the same MSIL.

Can anyone please enlighten me?

Best Regards,

Steve
 
P

Peter Bradley

My guess - and it is just a guess - is that the implicit cast probably uses
the ToString() method anyway. I would have thought any difference between
the two would have been optimized away by the compiler, but what do I know?

One thing's for sure, if you (or rather your prospective employers) need to
worry about performance at this level, then they're using the wrong
language. To me, it's on a par with worrying about whether:

i++;

is more efficient than:

++i;

Who cares. If you're writing code where these differences are significant,
use C or C++, or even Assembly language.

Just my 2c. YMMV.


Peter
 
G

glenn

Steve

The code with the ToString() call would be quicker 'cus I don't think the
first would even compile.

Personally, I think it should have been

Console.WriteLine( "This value is: {0}", i );

In this case ToString would be called anyway, so an explicit call to
ToString() is superfluous.

Glenn
 
D

DeveloperX

Hi,

I recently had an interview where I was asked a number of questions on C#.
Unfortunately I didn't get the answers from the test and find that one of
them is still niggling me.

It was something like this:

Consider the following code:

int i = 0;
Console.WriteLine("The value is: " + i);
Console.WriteLine("The value is: " + i.ToString());

Which would you use to write an integer to the console and why would it give
better performance?

I said I would use: Console.WriteLine("The value is: " +
i.ToString());

But I can't think why this should give a performance advantage. I can only
guess that the compiler should be able to realise that a string is required
from the integer for the line not using the ToString() method and generate
the same MSIL.

Can anyone please enlighten me?

Best Regards,

Steve

Well if we look at the IL of the two statements you can see the IL
takes a slightly different route on each go:

Here's the first one ( Console.WriteLine("The value is: " + i) ):

L_0007: call void [mscorlib]System.Console::WriteLine(string)
L_000c: ldstr "The value is: "
L_0011: ldloc.0
L_0012: box int32
L_0017: call string [mscorlib]System.String::Concat(object,
object)
L_001c: call void [mscorlib]System.Console::WriteLine(string)

And here's the second:

L_0026: call void [mscorlib]System.Console::WriteLine(string)
L_002b: ldstr "The value is: "
L_0030: ldloca.s i
L_0032: call instance string [mscorlib]System.Int32::ToString()
L_0037: call string [mscorlib]System.String::Concat(string,
string)
L_003c: call void [mscorlib]System.Console::WriteLine(string)

Now the two things that leap out immediately, in the first
String.Concat is called taking two objects and the int is boxed.
Boxing always carries an overhead. It has to be boxed to pass it as an
object (value type and reference type issue).

In the second it calls Concat taking two strings.
Here's the interesting bit. If we look at Concat(object, object) we
see

public static string Concat(object arg0, object arg1)
{
if (arg0 == null)
{
arg0 = Empty;
}
if (arg1 == null)
{
arg1 = Empty;
}
return (arg0.ToString() + arg1.ToString());
}


So it takes the two objects and attempts to call ToString on both of
them. Internally then it looks like the first lot of IL that uses the
two object signature will end up calling an internal version of the
second lot of IL, ie calling string.Concat(string, string).

Therefore I'd say the second version is quicker as it only runs Concat
once.
 
M

Mark Rae

One thing's for sure, if you (or rather your prospective employers) need
to worry about performance at this level, then they're using the wrong
language.

I couldn't agree more!!! What an utterly pointless and irrelevant
question...

Having been on both sides of the interview process many times over the
years, if you want to find out whether the prospective candidate is a good
developer or not, the most useful question is "Tell me about your last
development project"... You'll know in probably less than a minute if you
want to hire the person or not...
 
G

glenn

Peter

You could argue they're testing the depth of knowledge by asking the
question, but I do agree, I wouldn't like to work for a company that
constantly questioned my choice of string concatenation technique.

Glenn
 
L

Laura T.

The first version, Console.WriteLine("The value is: " + i);, would force the
compiler to box the value of i into a reference type, and because of boxing,
it would also use string.Concat(object,object) which is slower than
string.Concat(string,string).

The second version, Console.WriteLine("The value is: " + i.ToString());,
needs no boxing and it would use string.Concate(string,string).
 
G

glenn

I'm wrong, of course it would compile.

Must read documentation before posting, must read documentation before
posting...
 
G

Guest

Hi Peter and Gelnn.

Thankyou for your comments.

It does compile by the way.

It could have been:
Console.WriteLine( "This value is: {0}", i );
I can't remember exactly.

I didn't get the job by the way. I narrowly missed out by a few percent on
the passmark and this question is one that cost me.

It does seem reasonable to me that the compiler should be able to deal with
it, as you mention.

Oh well I will know what to say next time.

Thanks once again.

Steve.
 
M

Mike Schilling

Steve Bugden said:
Hi,

I recently had an interview where I was asked a number of questions on C#.
Unfortunately I didn't get the answers from the test and find that one of
them is still niggling me.

It was something like this:

Consider the following code:

int i = 0;
Console.WriteLine("The value is: " + i);
Console.WriteLine("The value is: " + i.ToString());

Which would you use to write an integer to the console and why would it
give
better performance?

By definition, they mean exactly the same thing, so it doesn't matter which
one you use. (If it were possible for "i" to be null, the first one would
be better, since it could never cause a null reference exception, but a
value type can't be null.) The analyses in other posts in the thread aren't
about the difference between these two statements, they're about what IL a
particular version of the compiler happens to generate. If these people
expect you to know that off the top of your head, they're idiots. Likewise,
if these people think that the difference between the two sets of generated
IL cause any measurable difference in performance, they're idiots.
 
M

Mark Rae

I didn't get the job by the way. I narrowly missed out by a few percent on
the passmark and this question is one that cost me.

Perhaps you can take comfort in the fact that you probably wouldn't want to
work for a company like that anyway... I know I certainly wouldn't!
 
D

DeveloperX

I couldn't agree more!!! What an utterly pointless and irrelevant
question...

Having been on both sides of the interview process many times over the
years, if you want to find out whether the prospective candidate is a good
developer or not, the most useful question is "Tell me about your last
development project"... You'll know in probably less than a minute if you
want to hire the person or not...

I don't know, I think there's something to be said for making sure a
candidate could/would take a stab at answering it. I imagine the
interviewer was less interested in the performance, but more
interested in showing the candidate understood boxing and overloaded
methods.
More importantly (hopefully) they were testing to see how the
candidate responds to a question they don't immediately know the
answer to. I mean if you just say "No idea" I probably wouldn't be too
impressed. In the first instance I'd like to see the developer show
some of that problem solving ability we're supposed to be known for.
If they at least had a stab at it, asked questions, even if they
didn't get there in the end I'd still respect the fact they tried.
Further if the candidate didn't get to the answer I'd take the time to
explain the answer and then see if they absorbed that information.
After all most programming questions can be answered with a quick
Google these days, it's whether they could take what they found on
Google, comprehend it and turn it into a solution.
I'd also say I would take a different approach to interviewing at
different levels. A junior candidate would be about potential, a
senior candidate about delivery and the questions would vary for both.
 
?

=?ISO-8859-1?Q?G=F6ran_Andersson?=

Mike said:
By definition, they mean exactly the same thing, so it doesn't matter which
one you use.

No, they don't mean the same thing. The result is the same, but that is
something completely different.
(If it were possible for "i" to be null, the first one would
be better, since it could never cause a null reference exception, but a
value type can't be null.) The analyses in other posts in the thread aren't
about the difference between these two statements, they're about what IL a
particular version of the compiler happens to generate.

Analysing the IL code is a way to find out how the compiler interprets
the code. It reveals that the code is equivalent to:

int i = 0;
Console.WriteLine(string.Concat((object)"The value is: ", (object)i));
Console.WriteLine(string.Concat("The value is: ", i.ToString()));
If these people
expect you to know that off the top of your head, they're idiots. Likewise,
if these people think that the difference between the two sets of generated
IL cause any measurable difference in performance, they're idiots.

Knowing how the compiler interprets the code is important in order to
avoid things like unintended conversions and boxing.

It's true that this example will not give a measurable difference in
performance, but the code demonstrates a difference in performance that
would be measurable in other situations. If you box a value type once,
it doesn't make a noticable difference, but if you do it in a loop that
runs a million iterations, there will be a difference.

The question is not intended to find out how you would optimise the
given code, as that code is in no need of optimising, but it's intended
to find out if you are aware of what the code is doing, and if you would
know how to optimise it in a situation where it would be needed.
 
G

Guest

Hi,

From the previous reply:
If these people
expect you to know that off the top of your head, they're idiots. Likewise,
if these people think that the difference between the two sets of generated
IL cause any measurable difference in performance, they're idiots.

I didn't get the job but I do feel a lot better now :)

Thanks to everyone for the interesting answers.

Best Regards,

Steve.
 
D

DeveloperX

By definition, they mean exactly the same thing, so it doesn't matter which
one you use. (If it were possible for "i" to be null, the first one would
be better, since it could never cause a null reference exception, but a
value type can't be null.) The analyses in other posts in the thread aren't
about the difference between these two statements, they're about what IL a
particular version of the compiler happens to generate. If these people
expect you to know that off the top of your head, they're idiots. Likewise,
if these people think that the difference between the two sets of generated
IL cause any measurable difference in performance, they're idiots.










- Show quoted text -- Hide quoted text -

- Show quoted text -

Sorry but that just isn't true.
The IL shows perfectly the different behaviours of the two lines. The
first will box into an object, call Concat(object, object) which
internally will call Concat(string, string). The second only calls
Concat(string, string) Any internal compiler optimisations would have
to honour that behaviour. So the IL disassembly shows exactly what the
difference between the two lines of code are and would not be markedly
different regardless of whether you compiled it under VS or say Mono.
The OP wanted to know what the difference was based on his interview
and he got several good answers.

Regarding performance. One is more performant than the other. Running
the above example won't yield a noticable difference in speed, doing
so with a more complex example in a tight loop over millions of
iterations would. I don't see why you'd use the less performant, less
dotnet (read strongly typed is good) approach and I don't understand
this sort of backlash against trying to make your code run as quickly
and efficiently as possible. The method Go() at the end of this post
shows the second loop runs 5-10pc quicker than the first loop.

As for whether anyone should know that off the top of their head, I'd
expect them to know about boxing and what problems it can cause and
I'd expect them to be able to ask the right questions to get to the
answer even if they needed help to do so.

And good luck on future interviews Steve.

private static void Go()
{
int s1 = System.Environment.TickCount;
string s;
int c;
for(c=0;c<10000000;c++)
{
s = "The value is:" + c;
s = string.Empty;
}
int s2 = System.Environment.TickCount;
for(c=0;c<10000000;c++)
{
s = "The value is:" + c.ToString();
s = string.Empty;
}
int s3 = System.Environment.TickCount;
Console.WriteLine("{0}\n\r{1}\n
\r{2}",s1.ToString(),s2.ToString(),s3.ToString());
Console.ReadLine();
}
 
J

Jon Skeet [C# MVP]

Regarding performance. One is more performant than the other. Running
the above example won't yield a noticable difference in speed, doing
so with a more complex example in a tight loop over millions of
iterations would. I don't see why you'd use the less performant, less
dotnet (read strongly typed is good) approach and I don't understand
this sort of backlash against trying to make your code run as quickly
and efficiently as possible.

One word: readability. The most readable code often isn't quite the
most performant, but most of the time it doesn't matter. When offered
the choice between:

Console.WriteLine ("i="+i);
and
Console.WriteLine ("i="+i.ToString());

I know which one I find more readable - the one with less fluff. Does
it perform less well? Slightly - in a way which isn't going to matter.
Is it less type-safe? No.

In short, I'd use the first version, even though it's slightly less
performant. In most cases, developer/maintainer time is much more
important than CPU time.

Jon
 
S

Samuel R. Neff

I would love it if every person I interviewed went into enough
technical detail to provide a basis for evaluation when talking about
their last project. However, I've found that more often then not it's
like pulling teeth to get technical details out of candidates (which
sometimes is reason enough to end the interview). Most of the time
people talk about the project and what it does and rarely offer up
technical details about what they did in the project or how the wrote
it or why they made the decisions they made.

I do have a list of trivia questions I bring to interviews for when I
need to I ask them, but I always prefer candiates that can talk well
enough about their jobs and theoretical projects that I don't have to
ask trivia. Usually if I drop to the trivia, it's just to confirm
that they're not worth hiring--or if I get someone that's really cocky
I ask them a particular question that nobody ever gets right (related
to boxing).

Sam


------------------------------------------------------------
We're hiring! B-Line Medical is seeking .NET
Developers for exciting positions in medical product
development in MD/DC. Work with a variety of technologies
in a relaxed team environment. See ads on Dice.com.
 
L

Laura T.

There is a more subtle difference.
The boxed version needs to allocate an object that non boxed version does
not.
For example, in your Go, the first loop would allocate 10000000 "extra"
Int32 objects.
Sometimes this behavior can make a difference.
 
D

DeveloperX

One word: readability. The most readable code often isn't quite the
most performant, but most of the time it doesn't matter. When offered
the choice between:

Console.WriteLine ("i="+i);
and
Console.WriteLine ("i="+i.ToString());

I know which one I find more readable - the one with less fluff. Does
it perform less well? Slightly - in a way which isn't going to matter.
Is it less type-safe? No.

In short, I'd use the first version, even though it's slightly less
performant. In most cases, developer/maintainer time is much more
important than CPU time.

Jon

I agree it's type safe, but the former passes an int and a string as
object parameters and the latter two strings to string parameters.
Given the choice I'd rather use the most accurate signature available
for what I want to do, in this case concat two strings. Ok, string
concatenation probably isn't the best example as it's really simple
and I do take your point on readability. I personally think I prefer
the ToString version as it's obvious that I want the int's string
representation. Imagine this example:

int i=1;
int j=2;
Console.WriteLine("My value is: " + i + j);
Console.WriteLine("My value is: " + (i + j));
Console.WriteLine(i + j);

Suddenly I get
My value is: 12
My value is: 3
3

So if a developer simply removed the string literal the intention of
the line of code changes.
 
M

Mike Schilling

DeveloperX said:
Sorry but that just isn't true.
The IL shows perfectly the different behaviours of the two lines. The
first will box into an object, call Concat(object, object) which
internally will call Concat(string, string). The second only calls
Concat(string, string) Any internal compiler optimisations would have
to honour that behaviour.

Why, when they result in identical behavior? C# is a high-level language,
not assembler.

So the IL disassembly shows exactly what the
difference between the two lines of code are and would not be markedly
different regardless of whether you compiled it under VS or say Mono.
The OP wanted to know what the difference was based on his interview
and he got several good answers.

Regarding performance. One is more performant than the other. Running
the above example won't yield a noticable difference in speed, doing
so with a more complex example in a tight loop over millions of
iterations would.

Can you demonstrate that? Seriously, build a test and tell us the results.
 

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

Top