Velocity Reviews > C is NOT significantly more efficient than C Sharp

# C is NOT significantly more efficient than C Sharp

spinoza1111
Guest
Posts: n/a

 12-27-2009
This is C code, which calculates the factorial of 19 1000000 times
both iteratively and recursively:

#include <stdio.h>
#include <time.h>

long long factorial(long long N)
{
long long nFactorialRecursive;
long long nFactorialIterative;
long long Nwork;
if (N <= 2) return N;
for ( nFactorialIterative = 1, Nwork = N;
Nwork > 1;
Nwork-- )
nFactorialIterative *= Nwork;
nFactorialRecursive = N * factorial(N-1);
if (nFactorialRecursive != nFactorialIterative)
printf("The iterative factorial of %I64d is %I64d but its recursive
factorial is %I64d\n",
N,
nFactorialIterative,
nFactorialRecursive);
return nFactorialRecursive;
}

int main(void)
{
long long N;
long long Nfactorial;
double dif;
long long i;
long long K;
time_t start;
time_t end;
N = 19;
K = 1000000;
time (&start);
for (i = 0; i < K; i++)
Nfactorial = factorial(N);
time (&end);
dif = difftime (end,start);
printf("The factorial of %I64d is %I64d: %.2f seconds to calculate
%I64d times\n",
N, Nfactorial, dif, K);
return 0;
}

Here is the equivalent C Sharp code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
public partial class findStudentNames : Form
{
private RichTextBox RTBinput = null;
private RichTextBox RTBoutput = null;

private const double WIDTH_TOLERANCE = .75;
private const double HEIGHT_TOLERANCE = .75;
private const double TEXTBOX_RATIO = .85;

private struct TYPname
{
private string STRfirst;
private string STRchinese;
private string STRpatronym;
public TYPname(string strFirst,
string strChinese,
string strPatronym)
{
STRfirst = strFirst.Trim();
STRchinese = strChinese.Trim();
STRpatronym = strPatronym.Trim();
}
public string toString()
{
return STRfirst + " " +
(STRchinese == ""
?
""
:
"(" + STRchinese + ")") + " " +
STRpatronym;
}
}

public findStudentNames()
{
InitializeComponent();
}

private void cmdFind_Click(object objSender,
EventArgs objEventArgs)
{
findNames_();
}

EventArgs objEventArgs)
{
customizeForm_();
}

private void customizeForm_()
{
try
{
this.Text = "findStudentNames";
this.Show();
this.Opacity = .5;
this.Refresh();
this.FormBorderStyle = FormBorderStyle.Fixed3D;
this.MinimizeBox = false;
this.MaximizeBox = false;
this.Width = (int)

(windowsUtilities.windowsUtilities.screenWidth()
*
WIDTH_TOLERANCE);
this.Height = (int)

(windowsUtilities.windowsUtilities.screenHeight()
*
HEIGHT_TOLERANCE);
int intGrid =
windowsUtilities.windowsUtilities.Grid;
int intGrid2 = intGrid << 1;
int intAvailable = 0;
(RTBinput =
windowsUtilities.windowsUtilities.mkRichTextBox
("",
intGrid,
intGrid,
(int)
((intAvailable = ClientSize.Width - intGrid2)
*
TEXTBOX_RATIO),
ClientSize.Height
-
intGrid * 3
-

windowsUtilities.windowsUtilities.defaultButtonHei ght()));
RTBinput.Font = new Font(FontFamily.GenericMonospace,
10);
RTBinput.ScrollBars = RichTextBoxScrollBars.Vertical;
RTBinput.Multiline = true;
RTBinput.WordWrap = false;
(RTBoutput =
windowsUtilities.windowsUtilities.mkRichTextBox
("",
RTBinput.Right,
RTBinput.Top,
intAvailable - RTBinput.Width,
RTBinput.Height));
RTBoutput.Font = new Font(FontFamily.GenericMonospace,
10);
RTBoutput.ScrollBars = RichTextBoxScrollBars.None;
RTBoutput.Multiline = true;
RTBoutput.WordWrap = false;
Button cmdNew = null;
(cmdNew =
windowsUtilities.windowsUtilities.mkButton
("Find",
intGrid,
RTBinput.Bottom + intGrid));
cmdNew.Click += cmdFind_Click;
this.CenterToScreen();
this.Opacity = 1;
this.Refresh();
}
catch (Exception objException)
{
throw new Exception("Can't customize form",
objException);
}
}

private void findNames_()
{
int intIndex1 = 0;
TYPname usrName = new TYPname("", "", "");
string strName = "";
int intNameLengthInSource = 0;
ref intIndex1))
{
if (find__locateName_(RTBinput.Text,
ref intIndex1,
ref usrName,
ref intNameLengthInSource)
&&
RTBoutput.Text.IndexOf
(strName = usrName.toString())
==
-1)
{
RTBoutput.Text +=
(RTBoutput.Text == ""
?
""
:
Environment.NewLine) +
strName;
RTBinput.SelectionStart = intIndex1;
RTBinput.SelectionLength =
intNameLengthInSource;
RTBinput.SelectionColor = Color.Red;
RTBinput.SelectionFont = new
Font(RTBinput.Font, FontStyle.Bold);
RTBoutput.Refresh();
}
}
}

private static bool find__locateName_
(string strTextNext,
ref int intIndex,
ref TYPname usrName,
ref int intNameLengthInSource)
{
intNameLengthInSource = 0;
if (find__locateName__isName_(strTextNext.Substring
(intIndex),
ref usrName,
ref intNameLengthInSource))
return true;
return false;
}

//
// name := ALPHA_STRING
// [ "(" (ALPHA_STRING [ " " ALPHA_STRING ] )* ")" ]
// ALPHA_STRING
//
private static bool find__locateName__isName_
(string strCandidate,
ref TYPname usrName,
ref int intLength)
{
intLength = 0;
string strFirst = "";
string strChinese = "";
string strPatronym = "";
int intIndex1 = 0;
find__locateName__isName__skipBlanks_
(strCandidate, ref intIndex1);
return find__locateName__isName__alphaString_
(strCandidate,
ref intLength,
ref strFirst)
&&
find__locateName__isName__chinese_
(strCandidate,
ref intLength,
ref strChinese)
&&
find__locateName__isName__alphaString_
(strCandidate,
ref intLength,
ref strPatronym);
}

private static bool find__locateName__isName__alphaString_
(string strCandidate,
ref int intIndex,
ref string strValue)
{
int intIndex1 = intIndex;
intIndex = utilities.utilities.verify
(strCandidate,
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
"abcdefghijklmnopqrstuvwxyz",
intIndex);
strValue = strCandidate.Substring
(intIndex1, intIndex - intIndex1);
return strValue != "";
}

private static bool find__locateName__isName__chinese_
(string strCandidate,
ref int intIndex,
ref string strValue)
{
strValue = "";
find__locateName__isName__skipBlanks_
(strCandidate, ref intIndex);
if (intIndex >= strCandidate.Length
||
strCandidate[intIndex++] != '(') return false;
int intIndex1 = 0;
while (intIndex >= strCandidate.Length
||
strCandidate[intIndex] != ')')
{
strValue =
strValue +
(strValue != "" ? " " : "") +
(strCandidate + " ").Substring
(intIndex,
(intIndex1
=
strCandidate.IndexOf(' ', intIndex))
-
intIndex);
intIndex = intIndex1;
find__locateName__isName__skipBlanks_
(strCandidate, ref intIndex);
}
return strValue != "";
}

private static void find__locateName__isName__skipBlanks_
(string strCandidate,
ref int intIndex)
{
for (;
intIndex < strCandidate.Length
&&
strCandidate[intIndex] == ' ';
intIndex++);
}

(string strText, ref int intIndex)
{
intIndex = utilities.utilities.verify
(strText + "0", "", intIndex, true)
-
1;
return intIndex < strText.Length;
}

}
}

The C code is only ten percent faster, and this is explained by set up
time for the threaded-code environment (and the benefits of safety and
platform independence) in the C Sharp code.

It is an Urban Legend, of course, that C Sharp is interpreted whereas
C is not. This is incorrect, since if it were, the execution time of
the C Sharp code would be in this particular example several orders of
magnitude larger owing to the amount of recursion and looping in the
example.

In the C Sharp environment, bytecodes cause control to be transferred
to handlers. There is NO parsing, scanning or analysis needed when
instructions are revisited.

Like the American constitution, the code is "a machine that would run
of itself".

And like our Constitution at its best, while it runs it provides a
certain level of assurance that nasty things won't happen, as opposed
let us say to the British constitution, which is constantly
interpretable by Parliament. There's no assurance, for example, that a
Mad King Charles won't in the near future refuse Royal Assent to some
measure.

A basic barbarism and regression, which is also evident in the
abominable treatment of Mr Wang Yip in the Void Main thread, makes
people want to "control" things.

bartc
Guest
Posts: n/a

 12-27-2009
"spinoza1111" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...

> Here is the equivalent C Sharp code:

> windowsUtilities.windowsUtilities.defaultButtonHei ght()));

Is this actual C# code? Why do you have to write windowsUtilities twice?

> The C code is only ten percent faster, and this is explained by set up
> time for the threaded-code environment (and the benefits of safety and
> platform independence) in the C Sharp code.

The C# appears to be an utterly different program; the first rule about
benchmarking language implementations is to compare like with like.

> It is an Urban Legend, of course, that C Sharp is interpreted whereas
> C is not. This is incorrect, since if it were, the execution time of
> the C Sharp code would be in this particular example several orders of
> magnitude larger owing to the amount of recursion and looping in the
> example.

I doubt whether recursion and looping enters into it. Typical bytecode
interpreters are one or two magnitudes slower than C, not several. C# uses a
more sophisticated scheme, last time I looked. It is somewhat slower than C
but is used in areas where this is not relevant.

--
Bartc

Flash Gordon
Guest
Posts: n/a

 12-27-2009
bartc wrote:
> "spinoza1111" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...

<snip>

>> The C code is only ten percent faster, and this is explained by set up
>> time for the threaded-code environment (and the benefits of safety and
>> platform independence) in the C Sharp code.

>
> The C# appears to be an utterly different program; the first rule about
> benchmarking language implementations is to compare like with like.

Don't you realise that it is your fault for not making the obvious
substitution of a program which actually calculates the factorial for
one which does something completely different?

<snip>

> I doubt whether recursion and looping enters into it. Typical bytecode
> interpreters are one or two magnitudes slower than C, not several. C#
> uses a more sophisticated scheme, last time I looked. It is somewhat
> slower than C but is used in areas where this is not relevant.

It's far more interesting to see the difference when compiling the same
program in the same language to both byte code and native code. Then you
get to see the overhead of the byte code interpreter. Or to compare the
same program in different languages both compiled to byte code (or
native code) so you can see the difference in performance due to the
natural way for programming in the language.
--
Flash Gordon

Flash Gordon
Guest
Posts: n/a

 12-27-2009
bartc wrote:
> "spinoza1111" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...

<snip>

>> The C code is only ten percent faster, and this is explained by set up
>> time for the threaded-code environment (and the benefits of safety and
>> platform independence) in the C Sharp code.

>
> The C# appears to be an utterly different program; the first rule about
> benchmarking language implementations is to compare like with like.

Don't you realise that it is your fault for not making the obvious
substitution of a program which actually calculates the factorial for
one which does something completely different?

<snip>

> I doubt whether recursion and looping enters into it. Typical bytecode
> interpreters are one or two magnitudes slower than C, not several. C#
> uses a more sophisticated scheme, last time I looked. It is somewhat
> slower than C but is used in areas where this is not relevant.

It's far more interesting to see the difference when compiling the same
program in the same language to both byte code and native code. Then you
get to see the overhead of the byte code interpreter. Or to compare the
same program in different languages both compiled to byte code (or
native code) so you can see the difference in performance due to the
natural way for programming in the language.
--
Flash Gordon

bartc
Guest
Posts: n/a

 12-27-2009

"Flash Gordon" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)-gordon.me.uk...
> bartc wrote:

>> I doubt whether recursion and looping enters into it. Typical bytecode
>> interpreters are one or two magnitudes slower than C, not several. C#
>> uses a more sophisticated scheme, last time I looked. It is somewhat
>> slower than C but is used in areas where this is not relevant.

>
> It's far more interesting to see the difference when compiling the same
> program in the same language to both byte code and native code. Then you
> get to see the overhead of the byte code interpreter.

That would be interesting to see, but bytecode tends to be used for
different languages where it's more apt. Comparing to C is then harder
because it's tempting to use higher level features of the other language
(although this might be exactly what makes it viable to interpret rather
than compile).

(This is pretty much what I'm doing at the moment. I have plain, interpreted
(not JIT-compiled) bytecode, which when benchmarked against C using only
low-level code on a PC, is typically 6x slower when static typing is
introduced (otherwise nearer 10x). When there is lots of data memory
involved however, that 6x can reduce to 2x as slow, so simply using main
memory is as big an overhead as using bytecode!)

--
Bartc

spinoza1111
Guest
Posts: n/a

 12-27-2009
On Dec 27, 7:31*pm, "bartc" <(E-Mail Removed)> wrote:
> "spinoza1111" <(E-Mail Removed)> wrote in message
>
> news:(E-Mail Removed)...
>
> > Here is the equivalent C Sharp code:
> > windowsUtilities.windowsUtilities.defaultButtonHei ght()));

>
> Is this actual C# code? Why do you have to write windowsUtilities twice?
>
> > The C code is only ten percent faster, and this is explained by set up
> > time for the threaded-code environment (and the benefits of safety and
> > platform independence) in the C Sharp code.

>
> The C# appears to be an utterly different program; the first rule about
> benchmarking language implementations is to compare like with like.
>
> > It is an Urban Legend, of course, that C Sharp is interpreted whereas
> > C is not. This is incorrect, since if it were, the execution time of
> > the C Sharp code would be in this particular example several orders of
> > magnitude larger owing to the amount of recursion and looping in the
> > example.

>
> I doubt whether recursion and looping enters into it. Typical bytecode
> interpreters are one or two magnitudes slower than C, not several. C# uses a
> more sophisticated scheme, last time I looked. It is somewhat slower than C
> but is used in areas where this is not relevant.
>
> --
> Bartc

The post was made in error and then deleted. See its replacement at

spinoza1111
Guest
Posts: n/a

 12-27-2009
On Dec 27, 8:38*pm, Flash Gordon <(E-Mail Removed)> wrote:
> bartc wrote:
> > "spinoza1111" <(E-Mail Removed)> wrote in message
> >news:(E-Mail Removed)....

>
> <snip>
>
> >> The C code is only ten percent faster, and this is explained by set up
> >> time for the threaded-code environment (and the benefits of safety and
> >> platform independence) in the C Sharp code.

>
> > The C# appears to be an utterly different program; the first rule about
> > benchmarking language implementations is to compare like with like.

>
> Don't you realise that it is your fault for not making the obvious
> substitution of a program which actually calculates the factorial for
> one which does something completely different?
>
> <snip>
>
> > I doubt whether recursion and looping enters into it. Typical bytecode
> > interpreters are one or two magnitudes slower than C, not several. C#
> > uses a more sophisticated scheme, last time I looked. It is somewhat
> > slower than C but is used in areas where this is not relevant.

>
> It's far more interesting to see the difference when compiling the same
> program in the same language to both byte code and native code. Then you
> get to see the overhead of the byte code interpreter. Or to compare the
> same program in different languages both compiled to byte code (or
> native code) so you can see the difference in performance due to the
> natural way for programming in the language.
> --
> Flash Gordon

As I have said with respect to Heathfield's malicious lie concerning
my presence at comp.risks, a pure error indicates nothing about
credibility esp when retracted; I deleted the post.

The corrected post is now at

jacob navia
Guest
Posts: n/a

 12-27-2009
I transformed that program a bit. It calculates now factorial of 20, and
it does that 10 million times.

Note that the difftime function is not accurate. I used the utility "timethis".
Machine: Intel i7 (8 cores) with 12GB RAM

The results are:
-------------------------------------------------------------------------------------
D:\temp>csc /o tfact.cs C# Optimizations ON
Microsoft (R) Visual C# 2008 Compiler version 3.5.30729.1
for Microsoft (R) .NET Framework version 3.5
D:\temp>timethis tfact
TimeThis : Command Line : tfact
TimeThis : Start Time : Sun Dec 27 18:33:53 2009

The factorial of 20 is 2432902008176640000: 00:00:03.7460000 seconds to calculate 10000000 times

TimeThis : Command Line : tfact
TimeThis : Start Time : Sun Dec 27 18:33:53 2009
TimeThis : End Time : Sun Dec 27 18:33:57 2009
TimeThis : Elapsed Time : 00:00:03.804
---------------------------------------------------------------------------------------
D:\temp>cl -Ox tfact.c C optimizations ON
Microsoft (R) C/C++ Optimizing Compiler Version 15.00.21022.08 for x64
tfact.c
Microsoft (R) Incremental Linker Version 9.00.21022.08
/out:tfact.exe
tfact.obj
D:\temp>timethis tfact
TimeThis : Command Line : tfact
TimeThis : Start Time : Sun Dec 27 18:34:10 2009

The factorial of 20 is 2432902008176640000: 3.00 seconds to calculate 10000000 times

TimeThis : Command Line : tfact
TimeThis : Start Time : Sun Dec 27 18:34:10 2009
TimeThis : End Time : Sun Dec 27 18:34:13 2009
TimeThis : Elapsed Time : 00:00:02.666
D:\temp>

----------------------------------------------------------------------------------------

The result is clear: C takes 2.666 seconds, C# takes 3.804 seconds