Search
Why is D significantly slower than C# in this instance?
Apr 10, 2023
Artjom
Apr 10, 2023
Artjom
Apr 11, 2023
Artjom
Apr 12, 2023
WebFreak001
Apr 12, 2023
Ali Çehreli
Apr 12, 2023
bachmeier
Apr 12, 2023
Ali Çehreli
Apr 12, 2023
H. S. Teoh
Apr 12, 2023
Salih Dincer
Apr 13, 2023
Jacob Shtokolov
Apr 10, 2023
H. S. Teoh
Apr 10, 2023
Artjom
Apr 10, 2023
H. S. Teoh
Apr 10, 2023
max haughton
Apr 10, 2023
Artjom
Apr 10, 2023
ryuukk_
Apr 11, 2023
Walter Bright
Apr 12, 2023
WollyTheWombat

I have written this simple bruteforce algorithm that finds max sum of subsequence in some sequence, both in C# and D. And when the size of array is 1000000 elements - D is 20 seconds lated. Why?
D code (algorithm):
'
public int solveBruteForce()
{
int currMax = arr[0], currSum;
foreach (_; arr)
{
currSum = 0;
foreach (int el; arr)
{
currSum += el;
currMax = max(currSum, currMax);
}
}

``````    return currMax;
}
``````

'
D code (measuring exec time):
'
double measureTime()
{
StopWatch sw;
sw.start();
solveDynamic();
double sec = (to!double(sw.peek.total!"msecs") / 1000) + (to!double(sw.peek.total!"usecs") / 1000000);
return sec;
}
'
C# code (alg):
'
int EachOther(int[] array)
{
int current_max = array[0];
for (int i = 0; i < array.Length; i++)
{
int subset_sum = 0;
for (int j = i; j < array.Length; j++)
{
subset_sum += array[j];
current_max = Math.Max(subset_sum, current_max);
}
}
return current_max;
}
'
C# code (time measuring):
'
Stopwatch stopwatch = new Stopwatch();
for (int cur_size = 1000; cur_size <= size_max; cur_size *= 10)
{
int[] array = GenArray(cur_size);
stopwatch.Start();
EachOther(array);
stopwatch.Stop();
double time = (double)stopwatch.ElapsedTicks / Stopwatch.Frequency;
Console.Write("{0, -10}|", string.Format("{0:f7}", time));
}
Console.WriteLine();
'

On Monday, 10 April 2023 at 21:18:59 UTC, Artjom wrote:

>

I have written this simple bruteforce algorithm that finds max sum of subsequence in some sequence, both in C# and D. And when the size of array is 1000000 elements - D is 20 seconds lated. Why?
D code (algorithm):
'
public int solveBruteForce()
{
int currMax = arr[0], currSum;
foreach (_; arr)
{
currSum = 0;
foreach (int el; arr)
{
currSum += el;
currMax = max(currSum, currMax);
}
}

``````    return currMax;
}
``````

'
D code (measuring exec time):
'
double measureTime()
{
StopWatch sw;
sw.start();
solveDynamic();
double sec = (to!double(sw.peek.total!"msecs") / 1000) + (to!double(sw.peek.total!"usecs") / 1000000);
return sec;
}
'
C# code (alg):
'
int EachOther(int[] array)
{
int current_max = array[0];
for (int i = 0; i < array.Length; i++)
{
int subset_sum = 0;
for (int j = i; j < array.Length; j++)
{
subset_sum += array[j];
current_max = Math.Max(subset_sum, current_max);
}
}
return current_max;
}
'
C# code (time measuring):
'
Stopwatch stopwatch = new Stopwatch();
for (int cur_size = 1000; cur_size <= size_max; cur_size *= 10)
{
int[] array = GenArray(cur_size);
stopwatch.Start();
EachOther(array);
stopwatch.Stop();
double time = (double)stopwatch.ElapsedTicks / Stopwatch.Frequency;
Console.Write("{0, -10}|", string.Format("{0:f7}", time));
}
Console.WriteLine();
'

Sorry, wrong code formatting

>

D code (algorithm):

``````    public int solveBruteForce()
{
int currMax = arr[0], currSum;
foreach (_; arr)
{
currSum = 0;
foreach (int el; arr)
{
currSum += el;
currMax = max(currSum, currMax);
}
}

return currMax;
}
``````
>

D code (measuring exec time):

``````double measureTime()
{
StopWatch sw;
sw.start();
solveDynamic();
double sec = (to!double(sw.peek.total!"msecs") / 1000) + (to!double(sw.peek.total!"usecs") / 1000000);
return sec;
}
``````
>

C# code (alg):

``````int EachOther(int[] array)
{
int current_max = array[0];
for (int i = 0; i < array.Length; i++)
{
int subset_sum = 0;
for (int j = i; j < array.Length; j++)
{
subset_sum += array[j];
current_max = Math.Max(subset_sum, current_max);
}
}
return current_max;
}
``````
>

C# code (time measuring):

``````Stopwatch stopwatch = new Stopwatch();
for (int cur_size = 1000; cur_size <= size_max; cur_size *= 10)
{
int[] array = GenArray(cur_size);
stopwatch.Start();
EachOther(array);
stopwatch.Stop();
double time = (double)stopwatch.ElapsedTicks /
Stopwatch.Frequency;
Console.Write("{0, -10}|", string.Format("{0:f7}", time));
}
Console.WriteLine();
``````
```On Mon, Apr 10, 2023 at 09:18:59PM +0000, Artjom via Digitalmars-d wrote:
> I have written this simple bruteforce algorithm that finds max sum of subsequence in some sequence, both in C# and D. And when the size of array is 1000000 elements - D is 20 seconds lated. Why?

Which compiler are you using and what are the compiler options?

> D code (algorithm):
> '
>     public int solveBruteForce()
>     {
>         int currMax = arr[0], currSum;
>         foreach (_; arr)
>         {
>             currSum = 0;
>             foreach (int el; arr)
>             {
>                 currSum += el;
>                 currMax = max(currSum, currMax);
>             }
>         }
>
>         return currMax;
>     }
> '
> D code (measuring exec time):
> '
>     double measureTime()
>     {
>         StopWatch sw;
>         sw.start();
>         solveDynamic();

This doesn't call the above function solveBruteForce. What's the definition of solveDynamic?

>         double sec = (to!double(sw.peek.total!"msecs") / 1000) +
> (to!double(sw.peek.total!"usecs") / 1000000);
>         return sec;
>     }
[...]

T

--
Two wrongs don't make a right; but three rights do make a left...
```
```On Monday, 10 April 2023 at 21:40:40 UTC, H. S. Teoh wrote:
> On Mon, Apr 10, 2023 at 09:18:59PM +0000, Artjom via Digitalmars-d wrote:
>> I have written this simple bruteforce algorithm that finds max sum of subsequence in some sequence, both in C# and D. And when the size of array is 1000000 elements - D is 20 seconds lated. Why?
>
> Which compiler are you using and what are the compiler options?
>
>
>> D code (algorithm):
>> '
>>     public int solveBruteForce()
>>     {
>>         int currMax = arr[0], currSum;
>>         foreach (_; arr)
>>         {
>>             currSum = 0;
>>             foreach (int el; arr)
>>             {
>>                 currSum += el;
>>                 currMax = max(currSum, currMax);
>>             }
>>         }
>>
>>         return currMax;
>>     }
>> '
>> D code (measuring exec time):
>> '
>>     double measureTime()
>>     {
>>         StopWatch sw;
>>         sw.start();
>>         solveDynamic();
>
> This doesn't call the above function solveBruteForce. What's the definition of solveDynamic?
>
>
>>         double sec = (to!double(sw.peek.total!"msecs") / 1000) +
>> (to!double(sw.peek.total!"usecs") / 1000000);
>>         return sec;
>>     }
> [...]
>
>
> T

Sorry, accidentaly pasted solveDynamic() insted of solveBruteForce(), it's solveBruteForce() in the code though.
Im using DMD and compile like "dmd .\source\app.d .\classes\solver.d"
```
```On Mon, Apr 10, 2023 at 09:46:25PM +0000, Artjom via Digitalmars-d wrote: [...]
> Sorry, accidentaly pasted solveDynamic() insted of solveBruteForce(),
> it's solveBruteForce() in the code though.
> Im using DMD and compile like "dmd .\source\app.d .\classes\solver.d"

1) You're compiling without optimization (-O), so performance is not
guaranteed to be good.

2) For anything where performance is important, don't use DMD. Instead, use `gdc -O3` or `ldc2 -O2`.

T

--
What's the difference between a 4D tube and an overweight Dutchman?  One is a hollow spherinder, and the other is a spherical Hollander.
```
```On Monday, 10 April 2023 at 22:00:40 UTC, H. S. Teoh wrote:
> On Mon, Apr 10, 2023 at 09:46:25PM +0000, Artjom via Digitalmars-d wrote: [...]
>> Sorry, accidentaly pasted solveDynamic() insted of solveBruteForce(),
>> it's solveBruteForce() in the code though.
>> Im using DMD and compile like "dmd .\source\app.d .\classes\solver.d"
>
> 1) You're compiling without optimization (-O), so performance is not
> guaranteed to be good.
>
> 2) For anything where performance is important, don't use DMD. Instead, use `gdc -O3` or `ldc2 -O2`.
>
>
> T
Unless the result is actually used the optimizer may also strip out the code entirely.

```
```On Monday, 10 April 2023 at 22:00:40 UTC, H. S. Teoh wrote:
> On Mon, Apr 10, 2023 at 09:46:25PM +0000, Artjom via Digitalmars-d wrote: [...]
>> Sorry, accidentaly pasted solveDynamic() insted of solveBruteForce(),
>> it's solveBruteForce() in the code though.
>> Im using DMD and compile like "dmd .\source\app.d .\classes\solver.d"
>
> 1) You're compiling without optimization (-O), so performance is not
> guaranteed to be good.
>
> 2) For anything where performance is important, don't use DMD. Instead, use `gdc -O3` or `ldc2 -O2`.
>
>
> T

well, i tried running it with this flag and its still 8 seconds later than C#. gotta try gdc i guess
```
```Please format your code using markdown syntax

```D
// your code here
```

Also please share the  exact code you benchmark, the one you shared is incomplete

As other mentioned you are building in debug mode, dmd is not suited for performance, it's favors compile speed instead

As other mentioned please use LDC on windows/unix or GDC on unix with proper release flag: -O2 for LDC for example
```

On 4/10/23 5:29 PM, Artjom wrote:

> >

D code (algorithm):

``````     public int solveBruteForce()
{
int currMax = arr[0], currSum;
foreach (_; arr)
{
currSum = 0;
foreach (int el; arr)
{
currSum += el;
currMax = max(currSum, currMax);
}
}

return currMax;
}
``````

...

> >

C# code (alg):

``````int EachOther(int[] array)
{
int current_max = array[0];
for (int i = 0; i < array.Length; i++)
{
int subset_sum = 0;
for (int j = i; j < array.Length; j++)
{
subset_sum += array[j];
current_max = Math.Max(subset_sum, current_max);
}
}
return current_max;
}
``````

You realize these are 2 different loop setups?

Lining up pseudocode so you can see:

D: foreach(i; 0 .. len) foreach(j; 0 .. len)
C#: foreach(i; 0 .. len) foreach(j; i .. len)

-Steve

On 4/10/23 9:49 PM, Steven Schveighoffer wrote:

>

Lining up pseudocode so you can see:

oof, forgot the formatting ticks:

``````D:  foreach(i; 0 .. len) foreach(j; 0 .. len)
C#: foreach(i; 0 .. len) foreach(j; i .. len)
``````

-Steve

« First   ‹ Prev
1 2