By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,564 Members | 1,081 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,564 IT Pros & Developers. It's quick & easy.

Why is my Time algorithm so slow - Can anyone tell me why?

P: n/a
Hi,

I am new to C#. I have the same time scheduling program written in C++ and
it is 5 times faster than my version in C#.
Why is it so slow as I thought that C# was only a little slower than C++?
What am I doing wrong?

Here is my code:

using System;

class cMain

{

public static int Main()

{

int[,] TimeSchedule = new int[GlobalValues.kNoDays+1,7]

{

{ 0, 0, 0, 0, 0, 0, 0},

{ 1, 1, 2, 3, 4, 5,49},

{ 2, 23,27,36,38,45,47},

{ 3, 23,33,35,42,44,48},

{ 4, 24,29,35,39,40,46},

{ 5, 22,28,34,40,44,45},

{ 6, 1, 2, 6,11,17,20},

{ 7, 1, 2, 7,10,16,21},

{ 8, 1, 2, 8,13,15,18},

{ 9, 23,26,34,36,41,47},

{ 10, 1, 2, 9,12,14,19},

{ 11, 23,28,31,35,37,42},

{ 12, 25,34,37,40,45,48},

{ 13, 32,33,44,46,47,48},

{ 14, 24,25,26,27,37,48},

{ 15, 24,29,30,32,40,42},

{ 16, 1, 3, 6,10,15,19},

{ 17, 1, 3, 7,11,14,18},

{ 18, 22,23,25,35,42,43},

{ 19, 1, 3, 8,12,17,21},

{ 20, 31,33,34,40,43,45},

{ 21, 30,33,36,39,44,48},

{ 22, 25,29,37,38,41,48},

{ 23, 1, 3, 9,13,16,20},

{ 24, 1, 4, 6,13,14,21},

{ 25, 24,25,28,33,41,45},

{ 26, 22,26,31,38,40,48},

{ 27, 1, 4, 7,12,15,20},

{ 28, 24,26,27,31,33,43},

{ 29, 23,27,32,39,40,41},

{ 30, 1, 4, 8,11,16,19},

{ 31, 22,25,32,43,46,47},

{ 32, 22,33,37,39,42,47},

{ 33, 1, 4, 9,10,17,18},

{ 34, 27,35,38,39,45,46},

{ 35, 1, 5, 6,12,16,18},

{ 36, 1, 5, 7,13,17,19},

{ 37, 1, 5, 8,10,14,20},

{ 38, 1, 5, 9,11,15,21},

{ 39, 1, 6, 7, 8, 9,49},

{ 40, 26,29,36,42,45,46},

{ 41, 1,10,11,12,13,49},

{ 42, 1,14,15,16,17,49},

{ 43, 1,18,19,20,21,49},

{ 44, 28,31,32,37,46,47},

{ 45, 22,25,30,36,39,43},

{ 46, 24,37,41,43,44,45},

{ 47, 26,34,35,39,41,46},

{ 48, 27,30,32,38,42,45},

{ 49, 22,24,26,27,28,44},

{ 50, 23,24,32,34,38,39},

{ 51, 22,32,33,35,36,37},

{ 52, 22,28,29,38,41,44},

{ 53, 28,39,42,43,47,48},

{ 54, 27,30,35,40,41,47},

{ 55, 2, 3, 6, 7,12,13},

{ 56, 27,36,40,41,42,46},

{ 57, 2, 3, 8, 9,10,11},

{ 58, 28,30,31,36,37,39},

{ 59, 2, 3,14,15,20,21},

{ 60, 23,24,29,36,40,47},

{ 61, 29,31,33,38,41,43},

{ 62, 2, 3,16,17,18,19},

{ 63, 26,29,30,35,45,47},

{ 64, 22,25,27,29,34,43},

{ 65, 2, 4, 6, 9,15,16},

{ 66, 26,37,38,40,43,44},

{ 67, 26,30,32,34,41,42},

{ 68, 23,30,31,33,43,46},

{ 69, 25,31,35,39,44,47},

{ 70, 2, 4, 7, 8,14,17},

{ 71, 2, 4,10,13,19,20},

{ 72, 2, 4,11,12,18,21},

{ 73, 24,34,36,38,42,46},

{ 74, 2, 5, 6, 8,19,21},

{ 75, 2, 5, 7, 9,18,20},

{ 76, 22,24,31,41,45,48},

{ 77, 25,26,28,33,38,40},

{ 78, 2, 5,10,12,15,17},

{ 79, 2, 5,11,13,14,16},

{ 80, 2, 6,10,14,18,49},

{ 81, 2, 7,11,15,19,49},

{ 82, 2, 8,12,16,20,49},

{ 83, 2, 9,13,17,21,49},

{ 84, 23,26,29,32,39,45},

{ 85, 24,30,34,35,38,47},

{ 86, 3, 4, 6, 8,18,20},

{ 87, 3, 4, 7, 9,19,21},

{ 88, 3, 4,10,12,14,16},

{ 89, 3, 4,11,13,15,17},

{ 90, 3, 5, 6, 9,14,17},

{ 91, 3, 5, 7, 8,15,16},

{ 92, 27,28,29,31,34,37},

{ 93, 23,25,30,37,46,48},

{ 94, 3, 5,10,13,18,21},

{ 95, 3, 5,11,12,19,20},

{ 96, 3, 6,11,16,21,49},

{ 97, 3, 7,10,17,20,49},

{ 98, 6, 7,14,16,19,20},

{ 99, 3, 8,13,14,19,49},

{100, 3, 9,12,15,18,49},

{101, 6, 7,15,17,18,21},

{102, 6, 8,10,13,16,17},

{103, 6, 8,11,12,14,15},

{104, 6, 9,10,12,20,21},

{105, 6, 9,11,13,18,19},

{106, 25,31,32,35,36,44},

{107, 4, 5, 8, 9,12,13},

{108, 4, 5,14,15,18,19},

{109, 4, 5,16,17,20,21},

{110, 4, 6,12,17,19,49},

{111, 4, 7,13,16,18,49},

{112, 7, 8,10,12,18,19},

{113, 7, 8,11,13,20,21},

{114, 7, 9,10,13,14,15},

{115, 7, 9,11,12,16,17},

{116, 8, 9,14,16,18,21},

{117, 8, 9,15,17,19,20},

{118, 10,11,14,17,19,21},

{119, 10,11,15,16,18,20},

{120, 12,13,14,17,18,20},

{121, 12,13,15,16,19,21},

{122, 4, 8,10,15,21,49},

{123, 4, 9,11,14,20,49},

{124, 5, 6,13,15,20,49},

{125, 5, 7,12,14,21,49},

{126, 5, 8,11,17,18,49},

{127, 5, 9,10,16,19,49},

{128, 4, 5, 6, 7,10,11},

{129, 22,23,28,30,44,46},

{130, 27,29,33,34,44,48},

{131, 28,32,36,42,43,48},

{132, 25,26,31,40,41,44},

{133, 24,28,38,40,43,48},

{134, 28,35,36,43,47,48},

{135, 24,25,31,38,44,45},

{136, 26,28,41,43,45,48},

{137, 25,28,29,33,44,46},

{138, 27,30,31,37,43,44},

{139, 22,23,25,31,34,48},

{140, 23,25,27,28,33,37},

{141, 22,29,30,31,33,48},

{142, 22,34,37,43,44,46},

{143, 25,31,36,42,44,47},

{144, 38,39,40,41,42,47},

{145, 22,26,33,37,38,45},

{146, 24,27,34,39,42,47},

{147, 23,26,32,35,42,45},

{148, 28,32,35,39,43,48},

{149, 23,29,37,43,44,48},

{150, 22,27,28,31,46,48},

{151, 22,24,33,37,40,41},

{152, 25,28,30,33,34,43},

{153, 23,30,34,38,40,46},

{154, 26,30,32,36,39,45},

{155, 27,29,34,35,38,41},

{156, 26,29,32,45,46,47},

{157, 23,24,27,30,41,46},

{158, 23,29,30,36,39,42},

{159, 25,31,32,39,42,44},

{160, 24,32,35,36,38,41},

{161, 24,26,27,29,40,45},

{162, 27,32,34,35,36,40},

{163, 23,30,35,36,46,47}};

for (int lpcnt=1; lpcnt<=GlobalValues.kNoSeconds; lpcnt++)
GlobalValues.gaSumWorkDays[lpcnt]=0;

for (int mm=1 ; mm<=GlobalValues.kNoDays ; mm++)

{

GlobalValues.gaWorkDays[1]=TimeSchedule[mm,1];

GlobalValues.gaWorkDays[2]=TimeSchedule[mm,2];

GlobalValues.gaWorkDays[3]=TimeSchedule[mm,3];

GlobalValues.gaWorkDays[4]=TimeSchedule[mm,4];

GlobalValues.gaWorkDays[5]=TimeSchedule[mm,5];

GlobalValues.gaWorkDays[6]=TimeSchedule[mm,6];

CWeekTime.WeekTime();

}
int lnTotMissingTime=0;

int t = DateTime.Now.Minute*60+DateTime.Now.Second;

Console.WriteLine("TimeStarted "+t);

lnTotMissingTime=CVerifyMissingTime.VerifyMissingT ime();
Console.WriteLine("Total No of Missing Time {0} ",lnTotMissingTime);

t = DateTime.Now.Minute*60+DateTime.Now.Second;

Console.WriteLine("Time Ended "+t);

Console.ReadLine();

return 0;

}

}

public class GlobalValues

{

public const int kNoWeeks=49;

public const int kNoDays=163;

public const int kNoSeconds=18424;

public static int gnSumSeconds = 0;

public static int[] gaWorkDays= new int [7];

public static int[] gaSumWorkDays = new int[kNoSeconds+1];

public static int[,] gaSeconds = new int [kNoWeeks+1,4]

{

{0, 0, 0, 0},

{1, 0, 0, 0},

{2, 1081, 0, 0},

{3, 2116, 46, 1},

{4, 3106, 91, 2},

{5, 4052, 135, 3},

{6, 4955, 178, 4},

{7, 5816, 220, 5},

{8, 6636, 261, 6},

{9, 7416, 301, 7},

{10, 8157, 340, 8},

{11, 8860, 378, 9},

{12, 9526, 415, 10},

{13, 10156, 451, 11},

{14, 10751, 486, 12},

{15, 11312, 520, 13},

{16, 11840, 553, 14},

{17, 12336, 585, 15},

{18, 12801, 616, 16},

{19, 13236, 646, 17},

{20, 13642, 675, 18},

{21, 14020, 703, 19},

{22, 14371, 730, 20},

{23, 14696, 756, 21},

{24, 14996, 781, 22},

{25, 15272, 805, 23},

{26, 15525, 828, 24},

{27, 15756, 850, 25},

{28, 15966, 871, 26},

{29, 16156, 891, 27},

{30, 16327, 910, 28},

{31, 16480, 928, 29},

{32, 16616, 945, 30},

{33, 16736, 961, 31},

{34, 16841, 976, 32},

{35, 16932, 990, 33},

{36, 17010, 1003, 34},

{37, 17076, 1015, 35},

{38, 17131, 1026, 36},

{39, 17176, 1036, 37},

{40, 17212, 1045, 38},

{41, 17240, 1053, 39},

{42, 17261, 1060, 40},

{43, 17276, 1066, 41},

{44, 17286, 1071, 42},

{45, 17292, 1075, 43},

{46, 17295, 1078, 44},

{47, 17296, 1080, 45},

{48, 0, 1081, 46},

{49, 0, 0, 47}};

}

class CWeekTime

{

public static int WeekTime()

{

for (int s1=1 ; s1<=4 ; s1++)

{

for (int s2=s1+1 ; s2<=5 ; s2++)

{

for (int s3=s2+1 ; s3<=6 ; s3++)

{

GlobalValues.gnSumSeconds=GlobalValues.gaSeconds[GlobalValues.gaWorkDays[s1],1]+GlobalValues.gaSeconds[GlobalValues.gaWorkDays[s2],2]+GlobalValues.gaSeconds[GlobalValues.gaWorkDays[s3],3];

GlobalValues.gaSumWorkDays[GlobalValues.gnSumSeconds]=1;

}

}

}

return (0);

}

}

class CVerifyMissingTime

{

public static int VerifyMissingTime()

{

int lnSumMissingTime=0;

for (int xxxLoop=1 ; xxxLoop<=10; xxxLoop++)

{

lnSumMissingTime=0;

for (int lp1=1 ; lp1<=GlobalValues.kNoWeeks-5 ; lp1++)

{

for (int lp2=lp1+1 ; lp2<=GlobalValues.kNoWeeks-4 ; lp2++)

{

for (int lp3=lp2+1 ; lp3<=GlobalValues.kNoWeeks-3 ; lp3++)

{

for (int lp4=lp3+1 ; lp4<=GlobalValues.kNoWeeks-2 ; lp4++)

{

for (int lp5=lp4+1 ; lp5<=GlobalValues.kNoWeeks-1 ; lp5++)

{

for (int lp6=lp5+1 ; lp6<=GlobalValues.kNoWeeks ; lp6++)

{

if
(GlobalValues.gaSumWorkDays[GlobalValues.gaSeconds[lp1,1]+GlobalValues.gaSeconds[lp2,2]+GlobalValues.gaSeconds[lp3,3]]>0)

{

lp6=lp5=lp4=100;

continue;

}

if
(GlobalValues.gaSumWorkDays[GlobalValues.gaSeconds[lp1,1]+GlobalValues.gaSeconds[lp2,2]+GlobalValues.gaSeconds[lp4,3]]>0)

{

lp6=lp5=100;

continue;

}

if
(GlobalValues.gaSumWorkDays[GlobalValues.gaSeconds[lp1,1]+GlobalValues.gaSeconds[lp3,2]+GlobalValues.gaSeconds[lp4,3]]>0)

{

lp6=lp5=100;

continue;

}

if
(GlobalValues.gaSumWorkDays[GlobalValues.gaSeconds[lp2,1]+GlobalValues.gaSeconds[lp3,2]+GlobalValues.gaSeconds[lp4,3]]>0)

{

lp6=lp5=100;

continue;

}

if
(GlobalValues.gaSumWorkDays[GlobalValues.gaSeconds[lp1,1]+GlobalValues.gaSeconds[lp2,2]+GlobalValues.gaSeconds[lp5,3]]>0)

{

lp6=100;

continue;

}

if
(GlobalValues.gaSumWorkDays[GlobalValues.gaSeconds[lp1,1]+GlobalValues.gaSeconds[lp3,2]+GlobalValues.gaSeconds[lp5,3]]>0)

{

lp6=100;

continue;

}

if
(GlobalValues.gaSumWorkDays[GlobalValues.gaSeconds[lp1,1]+GlobalValues.gaSeconds[lp4,2]+GlobalValues.gaSeconds[lp5,3]]>0)

{

lp6=100;

continue;

}

if
(GlobalValues.gaSumWorkDays[GlobalValues.gaSeconds[lp2,1]+GlobalValues.gaSeconds[lp3,2]+GlobalValues.gaSeconds[lp5,3]]>0)

{

lp6=100;

continue;

}

if
(GlobalValues.gaSumWorkDays[GlobalValues.gaSeconds[lp2,1]+GlobalValues.gaSeconds[lp4,2]+GlobalValues.gaSeconds[lp5,3]]>0)

{

lp6=100;

continue;

}

if
(GlobalValues.gaSumWorkDays[GlobalValues.gaSeconds[lp3,1]+GlobalValues.gaSeconds[lp4,2]+GlobalValues.gaSeconds[lp5,3]]>0)

{

lp6=100;

continue;

}

if
(GlobalValues.gaSumWorkDays[GlobalValues.gaSeconds[lp1,1]+GlobalValues.gaSeconds[lp2,2]+GlobalValues.gaSeconds[lp6,3]]>0)

{

continue;

}

if
(GlobalValues.gaSumWorkDays[GlobalValues.gaSeconds[lp1,1]+GlobalValues.gaSeconds[lp3,2]+GlobalValues.gaSeconds[lp6,3]]>0)

{

continue;

}

if
(GlobalValues.gaSumWorkDays[GlobalValues.gaSeconds[lp1,1]+GlobalValues.gaSeconds[lp4,2]+GlobalValues.gaSeconds[lp6,3]]>0)

{

continue;

}

if
(GlobalValues.gaSumWorkDays[GlobalValues.gaSeconds[lp1,1]+GlobalValues.gaSeconds[lp5,2]+GlobalValues.gaSeconds[lp6,3]]>0)

{

continue;

}

if
(GlobalValues.gaSumWorkDays[GlobalValues.gaSeconds[lp2,1]+GlobalValues.gaSeconds[lp3,2]+GlobalValues.gaSeconds[lp6,3]]>0)

{

continue;

}

if
(GlobalValues.gaSumWorkDays[GlobalValues.gaSeconds[lp2,1]+GlobalValues.gaSeconds[lp4,2]+GlobalValues.gaSeconds[lp6,3]]>0)

{

continue;

}

if
(GlobalValues.gaSumWorkDays[GlobalValues.gaSeconds[lp2,1]+GlobalValues.gaSeconds[lp5,2]+GlobalValues.gaSeconds[lp6,3]]>0)

{

continue;

}

if
(GlobalValues.gaSumWorkDays[GlobalValues.gaSeconds[lp3,1]+GlobalValues.gaSeconds[lp4,2]+GlobalValues.gaSeconds[lp6,3]]>0)

{

continue;

}

if
(GlobalValues.gaSumWorkDays[GlobalValues.gaSeconds[lp3,1]+GlobalValues.gaSeconds[lp5,2]+GlobalValues.gaSeconds[lp6,3]]>0)

{

continue;

}

if
(GlobalValues.gaSumWorkDays[GlobalValues.gaSeconds[lp4,1]+GlobalValues.gaSeconds[lp5,2]+GlobalValues.gaSeconds[lp6,3]]>0)

{

continue;

}

lnSumMissingTime++;

}

}

}

}

}

}

}

Console.WriteLine("Missing Time {0}",lnSumMissingTime);

return lnSumMissingTime;

}

}

TIA

Roy

Nov 17 '05 #1
Share this Question
Share on Google+
29 Replies


P: n/a
Roy Gourgi <ro***@videotron.ca> wrote:
I am new to C#. I have the same time scheduling program written in C++ and
it is 5 times faster than my version in C#.
Why is it so slow as I thought that C# was only a little slower than C++?
What am I doing wrong?


Well, you haven't shown your C++ code, you haven't said what the
program is meant to be doing, and the code is frighteningly difficult
to understand (partly due to not being object-oriented at all, as far
as I can see), which doesn't really help.

I would start by refactoring it into a much easier to understand form,
and *then* look at the efficiency of it.

You could also try using jagged arrays instead of rectangular ones -
that's more efficient in .NET, and as the majority of your time seems
to be spent in that rather large set of if statements which do very
little other than array access, that could make a significant
difference.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Nov 17 '05 #2

P: n/a
Roy,

I am curious, why are you building your own time scheduling system? Why
not use the application scheduluer in windows to launch your application at
your scheduled times?

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Roy Gourgi" <ro***@videotron.ca> wrote in message
news:sY****************@weber.videotron.net...
Hi,

I am new to C#. I have the same time scheduling program written in C++ and
it is 5 times faster than my version in C#.
Why is it so slow as I thought that C# was only a little slower than C++?
What am I doing wrong?

Here is my code:

using System;

class cMain

{

public static int Main()

{

int[,] TimeSchedule = new int[GlobalValues.kNoDays+1,7]

{

{ 0, 0, 0, 0, 0, 0, 0},

{ 1, 1, 2, 3, 4, 5,49},

{ 2, 23,27,36,38,45,47},

{ 3, 23,33,35,42,44,48},

{ 4, 24,29,35,39,40,46},

{ 5, 22,28,34,40,44,45},

{ 6, 1, 2, 6,11,17,20},

{ 7, 1, 2, 7,10,16,21},

{ 8, 1, 2, 8,13,15,18},

{ 9, 23,26,34,36,41,47},

{ 10, 1, 2, 9,12,14,19},

{ 11, 23,28,31,35,37,42},

{ 12, 25,34,37,40,45,48},

{ 13, 32,33,44,46,47,48},

{ 14, 24,25,26,27,37,48},

{ 15, 24,29,30,32,40,42},

{ 16, 1, 3, 6,10,15,19},

{ 17, 1, 3, 7,11,14,18},

{ 18, 22,23,25,35,42,43},

{ 19, 1, 3, 8,12,17,21},

{ 20, 31,33,34,40,43,45},

{ 21, 30,33,36,39,44,48},

{ 22, 25,29,37,38,41,48},

{ 23, 1, 3, 9,13,16,20},

{ 24, 1, 4, 6,13,14,21},

{ 25, 24,25,28,33,41,45},

{ 26, 22,26,31,38,40,48},

{ 27, 1, 4, 7,12,15,20},

{ 28, 24,26,27,31,33,43},

{ 29, 23,27,32,39,40,41},

{ 30, 1, 4, 8,11,16,19},

{ 31, 22,25,32,43,46,47},

{ 32, 22,33,37,39,42,47},

{ 33, 1, 4, 9,10,17,18},

{ 34, 27,35,38,39,45,46},

{ 35, 1, 5, 6,12,16,18},

{ 36, 1, 5, 7,13,17,19},

{ 37, 1, 5, 8,10,14,20},

{ 38, 1, 5, 9,11,15,21},

{ 39, 1, 6, 7, 8, 9,49},

{ 40, 26,29,36,42,45,46},

{ 41, 1,10,11,12,13,49},

{ 42, 1,14,15,16,17,49},

{ 43, 1,18,19,20,21,49},

{ 44, 28,31,32,37,46,47},

{ 45, 22,25,30,36,39,43},

{ 46, 24,37,41,43,44,45},

{ 47, 26,34,35,39,41,46},

{ 48, 27,30,32,38,42,45},

{ 49, 22,24,26,27,28,44},

{ 50, 23,24,32,34,38,39},

{ 51, 22,32,33,35,36,37},

{ 52, 22,28,29,38,41,44},

{ 53, 28,39,42,43,47,48},

{ 54, 27,30,35,40,41,47},

{ 55, 2, 3, 6, 7,12,13},

{ 56, 27,36,40,41,42,46},

{ 57, 2, 3, 8, 9,10,11},

{ 58, 28,30,31,36,37,39},

{ 59, 2, 3,14,15,20,21},

{ 60, 23,24,29,36,40,47},

{ 61, 29,31,33,38,41,43},

{ 62, 2, 3,16,17,18,19},

{ 63, 26,29,30,35,45,47},

{ 64, 22,25,27,29,34,43},

{ 65, 2, 4, 6, 9,15,16},

{ 66, 26,37,38,40,43,44},

{ 67, 26,30,32,34,41,42},

{ 68, 23,30,31,33,43,46},

{ 69, 25,31,35,39,44,47},

{ 70, 2, 4, 7, 8,14,17},

{ 71, 2, 4,10,13,19,20},

{ 72, 2, 4,11,12,18,21},

{ 73, 24,34,36,38,42,46},

{ 74, 2, 5, 6, 8,19,21},

{ 75, 2, 5, 7, 9,18,20},

{ 76, 22,24,31,41,45,48},

{ 77, 25,26,28,33,38,40},

{ 78, 2, 5,10,12,15,17},

{ 79, 2, 5,11,13,14,16},

{ 80, 2, 6,10,14,18,49},

{ 81, 2, 7,11,15,19,49},

{ 82, 2, 8,12,16,20,49},

{ 83, 2, 9,13,17,21,49},

{ 84, 23,26,29,32,39,45},

{ 85, 24,30,34,35,38,47},

{ 86, 3, 4, 6, 8,18,20},

{ 87, 3, 4, 7, 9,19,21},

{ 88, 3, 4,10,12,14,16},

{ 89, 3, 4,11,13,15,17},

{ 90, 3, 5, 6, 9,14,17},

{ 91, 3, 5, 7, 8,15,16},

{ 92, 27,28,29,31,34,37},

{ 93, 23,25,30,37,46,48},

{ 94, 3, 5,10,13,18,21},

{ 95, 3, 5,11,12,19,20},

{ 96, 3, 6,11,16,21,49},

{ 97, 3, 7,10,17,20,49},

{ 98, 6, 7,14,16,19,20},

{ 99, 3, 8,13,14,19,49},

{100, 3, 9,12,15,18,49},

{101, 6, 7,15,17,18,21},

{102, 6, 8,10,13,16,17},

{103, 6, 8,11,12,14,15},

{104, 6, 9,10,12,20,21},

{105, 6, 9,11,13,18,19},

{106, 25,31,32,35,36,44},

{107, 4, 5, 8, 9,12,13},

{108, 4, 5,14,15,18,19},

{109, 4, 5,16,17,20,21},

{110, 4, 6,12,17,19,49},

{111, 4, 7,13,16,18,49},

{112, 7, 8,10,12,18,19},

{113, 7, 8,11,13,20,21},

{114, 7, 9,10,13,14,15},

{115, 7, 9,11,12,16,17},

{116, 8, 9,14,16,18,21},

{117, 8, 9,15,17,19,20},

{118, 10,11,14,17,19,21},

{119, 10,11,15,16,18,20},

{120, 12,13,14,17,18,20},

{121, 12,13,15,16,19,21},

{122, 4, 8,10,15,21,49},

{123, 4, 9,11,14,20,49},

{124, 5, 6,13,15,20,49},

{125, 5, 7,12,14,21,49},

{126, 5, 8,11,17,18,49},

{127, 5, 9,10,16,19,49},

{128, 4, 5, 6, 7,10,11},

{129, 22,23,28,30,44,46},

{130, 27,29,33,34,44,48},

{131, 28,32,36,42,43,48},

{132, 25,26,31,40,41,44},

{133, 24,28,38,40,43,48},

{134, 28,35,36,43,47,48},

{135, 24,25,31,38,44,45},

{136, 26,28,41,43,45,48},

{137, 25,28,29,33,44,46},

{138, 27,30,31,37,43,44},

{139, 22,23,25,31,34,48},

{140, 23,25,27,28,33,37},

{141, 22,29,30,31,33,48},

{142, 22,34,37,43,44,46},

{143, 25,31,36,42,44,47},

{144, 38,39,40,41,42,47},

{145, 22,26,33,37,38,45},

{146, 24,27,34,39,42,47},

{147, 23,26,32,35,42,45},

{148, 28,32,35,39,43,48},

{149, 23,29,37,43,44,48},

{150, 22,27,28,31,46,48},

{151, 22,24,33,37,40,41},

{152, 25,28,30,33,34,43},

{153, 23,30,34,38,40,46},

{154, 26,30,32,36,39,45},

{155, 27,29,34,35,38,41},

{156, 26,29,32,45,46,47},

{157, 23,24,27,30,41,46},

{158, 23,29,30,36,39,42},

{159, 25,31,32,39,42,44},

{160, 24,32,35,36,38,41},

{161, 24,26,27,29,40,45},

{162, 27,32,34,35,36,40},

{163, 23,30,35,36,46,47}};

for (int lpcnt=1; lpcnt<=GlobalValues.kNoSeconds; lpcnt++)
GlobalValues.gaSumWorkDays[lpcnt]=0;

for (int mm=1 ; mm<=GlobalValues.kNoDays ; mm++)

{

GlobalValues.gaWorkDays[1]=TimeSchedule[mm,1];

GlobalValues.gaWorkDays[2]=TimeSchedule[mm,2];

GlobalValues.gaWorkDays[3]=TimeSchedule[mm,3];

GlobalValues.gaWorkDays[4]=TimeSchedule[mm,4];

GlobalValues.gaWorkDays[5]=TimeSchedule[mm,5];

GlobalValues.gaWorkDays[6]=TimeSchedule[mm,6];

CWeekTime.WeekTime();

}
int lnTotMissingTime=0;

int t = DateTime.Now.Minute*60+DateTime.Now.Second;

Console.WriteLine("TimeStarted "+t);

lnTotMissingTime=CVerifyMissingTime.VerifyMissingT ime();
Console.WriteLine("Total No of Missing Time {0} ",lnTotMissingTime);

t = DateTime.Now.Minute*60+DateTime.Now.Second;

Console.WriteLine("Time Ended "+t);

Console.ReadLine();

return 0;

}

}

public class GlobalValues

{

public const int kNoWeeks=49;

public const int kNoDays=163;

public const int kNoSeconds=18424;

public static int gnSumSeconds = 0;

public static int[] gaWorkDays= new int [7];

public static int[] gaSumWorkDays = new int[kNoSeconds+1];

public static int[,] gaSeconds = new int [kNoWeeks+1,4]

{

{0, 0, 0, 0},

{1, 0, 0, 0},

{2, 1081, 0, 0},

{3, 2116, 46, 1},

{4, 3106, 91, 2},

{5, 4052, 135, 3},

{6, 4955, 178, 4},

{7, 5816, 220, 5},

{8, 6636, 261, 6},

{9, 7416, 301, 7},

{10, 8157, 340, 8},

{11, 8860, 378, 9},

{12, 9526, 415, 10},

{13, 10156, 451, 11},

{14, 10751, 486, 12},

{15, 11312, 520, 13},

{16, 11840, 553, 14},

{17, 12336, 585, 15},

{18, 12801, 616, 16},

{19, 13236, 646, 17},

{20, 13642, 675, 18},

{21, 14020, 703, 19},

{22, 14371, 730, 20},

{23, 14696, 756, 21},

{24, 14996, 781, 22},

{25, 15272, 805, 23},

{26, 15525, 828, 24},

{27, 15756, 850, 25},

{28, 15966, 871, 26},

{29, 16156, 891, 27},

{30, 16327, 910, 28},

{31, 16480, 928, 29},

{32, 16616, 945, 30},

{33, 16736, 961, 31},

{34, 16841, 976, 32},

{35, 16932, 990, 33},

{36, 17010, 1003, 34},

{37, 17076, 1015, 35},

{38, 17131, 1026, 36},

{39, 17176, 1036, 37},

{40, 17212, 1045, 38},

{41, 17240, 1053, 39},

{42, 17261, 1060, 40},

{43, 17276, 1066, 41},

{44, 17286, 1071, 42},

{45, 17292, 1075, 43},

{46, 17295, 1078, 44},

{47, 17296, 1080, 45},

{48, 0, 1081, 46},

{49, 0, 0, 47}};

}

class CWeekTime

{

public static int WeekTime()

{

for (int s1=1 ; s1<=4 ; s1++)

{

for (int s2=s1+1 ; s2<=5 ; s2++)

{

for (int s3=s2+1 ; s3<=6 ; s3++)

{

GlobalValues.gnSumSeconds=GlobalValues.gaSeconds[GlobalValues.gaWorkDays[s1],1]+GlobalValues.gaSeconds[GlobalValues.gaWorkDays[s2],2]+GlobalValues.gaSeconds[GlobalValues.gaWorkDays[s3],3];

GlobalValues.gaSumWorkDays[GlobalValues.gnSumSeconds]=1;

}

}

}

return (0);

}

}

class CVerifyMissingTime

{

public static int VerifyMissingTime()

{

int lnSumMissingTime=0;

for (int xxxLoop=1 ; xxxLoop<=10; xxxLoop++)

{

lnSumMissingTime=0;

for (int lp1=1 ; lp1<=GlobalValues.kNoWeeks-5 ; lp1++)

{

for (int lp2=lp1+1 ; lp2<=GlobalValues.kNoWeeks-4 ; lp2++)

{

for (int lp3=lp2+1 ; lp3<=GlobalValues.kNoWeeks-3 ; lp3++)

{

for (int lp4=lp3+1 ; lp4<=GlobalValues.kNoWeeks-2 ; lp4++)

{

for (int lp5=lp4+1 ; lp5<=GlobalValues.kNoWeeks-1 ; lp5++)

{

for (int lp6=lp5+1 ; lp6<=GlobalValues.kNoWeeks ; lp6++)

{

if
(GlobalValues.gaSumWorkDays[GlobalValues.gaSeconds[lp1,1]+GlobalValues.gaSeconds[lp2,2]+GlobalValues.gaSeconds[lp3,3]]>0)

{

lp6=lp5=lp4=100;

continue;

}

if
(GlobalValues.gaSumWorkDays[GlobalValues.gaSeconds[lp1,1]+GlobalValues.gaSeconds[lp2,2]+GlobalValues.gaSeconds[lp4,3]]>0)

{

lp6=lp5=100;

continue;

}

if
(GlobalValues.gaSumWorkDays[GlobalValues.gaSeconds[lp1,1]+GlobalValues.gaSeconds[lp3,2]+GlobalValues.gaSeconds[lp4,3]]>0)

{

lp6=lp5=100;

continue;

}

if
(GlobalValues.gaSumWorkDays[GlobalValues.gaSeconds[lp2,1]+GlobalValues.gaSeconds[lp3,2]+GlobalValues.gaSeconds[lp4,3]]>0)

{

lp6=lp5=100;

continue;

}

if
(GlobalValues.gaSumWorkDays[GlobalValues.gaSeconds[lp1,1]+GlobalValues.gaSeconds[lp2,2]+GlobalValues.gaSeconds[lp5,3]]>0)

{

lp6=100;

continue;

}

if
(GlobalValues.gaSumWorkDays[GlobalValues.gaSeconds[lp1,1]+GlobalValues.gaSeconds[lp3,2]+GlobalValues.gaSeconds[lp5,3]]>0)

{

lp6=100;

continue;

}

if
(GlobalValues.gaSumWorkDays[GlobalValues.gaSeconds[lp1,1]+GlobalValues.gaSeconds[lp4,2]+GlobalValues.gaSeconds[lp5,3]]>0)

{

lp6=100;

continue;

}

if
(GlobalValues.gaSumWorkDays[GlobalValues.gaSeconds[lp2,1]+GlobalValues.gaSeconds[lp3,2]+GlobalValues.gaSeconds[lp5,3]]>0)

{

lp6=100;

continue;

}

if
(GlobalValues.gaSumWorkDays[GlobalValues.gaSeconds[lp2,1]+GlobalValues.gaSeconds[lp4,2]+GlobalValues.gaSeconds[lp5,3]]>0)

{

lp6=100;

continue;

}

if
(GlobalValues.gaSumWorkDays[GlobalValues.gaSeconds[lp3,1]+GlobalValues.gaSeconds[lp4,2]+GlobalValues.gaSeconds[lp5,3]]>0)

{

lp6=100;

continue;

}

if
(GlobalValues.gaSumWorkDays[GlobalValues.gaSeconds[lp1,1]+GlobalValues.gaSeconds[lp2,2]+GlobalValues.gaSeconds[lp6,3]]>0)

{

continue;

}

if
(GlobalValues.gaSumWorkDays[GlobalValues.gaSeconds[lp1,1]+GlobalValues.gaSeconds[lp3,2]+GlobalValues.gaSeconds[lp6,3]]>0)

{

continue;

}

if
(GlobalValues.gaSumWorkDays[GlobalValues.gaSeconds[lp1,1]+GlobalValues.gaSeconds[lp4,2]+GlobalValues.gaSeconds[lp6,3]]>0)

{

continue;

}

if
(GlobalValues.gaSumWorkDays[GlobalValues.gaSeconds[lp1,1]+GlobalValues.gaSeconds[lp5,2]+GlobalValues.gaSeconds[lp6,3]]>0)

{

continue;

}

if
(GlobalValues.gaSumWorkDays[GlobalValues.gaSeconds[lp2,1]+GlobalValues.gaSeconds[lp3,2]+GlobalValues.gaSeconds[lp6,3]]>0)

{

continue;

}

if
(GlobalValues.gaSumWorkDays[GlobalValues.gaSeconds[lp2,1]+GlobalValues.gaSeconds[lp4,2]+GlobalValues.gaSeconds[lp6,3]]>0)

{

continue;

}

if
(GlobalValues.gaSumWorkDays[GlobalValues.gaSeconds[lp2,1]+GlobalValues.gaSeconds[lp5,2]+GlobalValues.gaSeconds[lp6,3]]>0)

{

continue;

}

if
(GlobalValues.gaSumWorkDays[GlobalValues.gaSeconds[lp3,1]+GlobalValues.gaSeconds[lp4,2]+GlobalValues.gaSeconds[lp6,3]]>0)

{

continue;

}

if
(GlobalValues.gaSumWorkDays[GlobalValues.gaSeconds[lp3,1]+GlobalValues.gaSeconds[lp5,2]+GlobalValues.gaSeconds[lp6,3]]>0)

{

continue;

}

if
(GlobalValues.gaSumWorkDays[GlobalValues.gaSeconds[lp4,1]+GlobalValues.gaSeconds[lp5,2]+GlobalValues.gaSeconds[lp6,3]]>0)

{

continue;

}

lnSumMissingTime++;

}

}

}

}

}

}

}

Console.WriteLine("Missing Time {0}",lnSumMissingTime);

return lnSumMissingTime;

}

}

TIA

Roy


Nov 17 '05 #3

P: n/a
Hi,

Basically, for all intensive purposes all I have is 2 arrays (gaSeconds &
TimeSchedule). The array gaSeconds as you can see, has to be accessed many,
many times and for this application, it cannot absolutely be a jagged array.
The values in the gaSeconds in the real application change, but I kept them
constant for the sake of simplicity, so although it looks that I am
aimlessly accessing the same information many times in the
CVerifyMissingTime, I am not.

All I wanted to know if there is a way to make this faster. I am not that
worried about wheter it is in classic object oriented programming form as
speed is of the essence.

So basically this is the program in a more intuitive way:
I have to create 2 arrays (that can be seen throughout the whole program)
and one of which will be accessed many times.
Thanks
Roy

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP***********************@msnews.microsoft.co m...
Roy Gourgi <ro***@videotron.ca> wrote:
I am new to C#. I have the same time scheduling program written in C++
and
it is 5 times faster than my version in C#.
Why is it so slow as I thought that C# was only a little slower than C++?
What am I doing wrong?


Well, you haven't shown your C++ code, you haven't said what the
program is meant to be doing, and the code is frighteningly difficult
to understand (partly due to not being object-oriented at all, as far
as I can see), which doesn't really help.

I would start by refactoring it into a much easier to understand form,
and *then* look at the efficiency of it.

You could also try using jagged arrays instead of rectangular ones -
that's more efficient in .NET, and as the majority of your time seems
to be spent in that rather large set of if statements which do very
little other than array access, that could make a significant
difference.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too

Nov 17 '05 #4

P: n/a
On Sun, 9 Oct 2005 10:39:09 +0100, "Roy Gourgi" <ro***@videotron.ca>
wrote:
Hi,

I am new to C#. I have the same time scheduling program written in C++ and
it is 5 times faster than my version in C#.
Why is it so slow as I thought that C# was only a little slower than C++?
What am I doing wrong?


First of all, in my experience c# isn't very good at handling multi
level loops so don't expect to ever get C++ performance with an
algorithm like that with the current c# compiler.

I can see a few ways of optimizing the code. The big winner as Jon
Skeet already suggested is to used make gaSeconsds jagged instead of
multidimensional. Even if it has to be multidimensional in the rest of
the program it will still pay off to convert it to jagged formet
before doing the calculations. This is the best way to increase
performance and will almost half the running time.

You recalculate quite a few of the array accesses multiple times. They
could be calculated and stored in local variables in the outer for
loops.

Finally replacing lp6=100; continue; with break; will give a small
performance boost.
Here is a rewrite of your code that runs a lot faster:
using System;

class cMain
{
public static int Main()
{
int[,] TimeSchedule = new int[GlobalValues.kNoDays + 1, 7]
{
{ 0, 0, 0, 0, 0, 0, 0},
{ 1, 1, 2, 3, 4, 5,49},
{ 2, 23,27,36,38,45,47},
{ 3, 23,33,35,42,44,48},
{ 4, 24,29,35,39,40,46},
{ 5, 22,28,34,40,44,45},
{ 6, 1, 2, 6,11,17,20},
{ 7, 1, 2, 7,10,16,21},
{ 8, 1, 2, 8,13,15,18},
{ 9, 23,26,34,36,41,47},
{ 10, 1, 2, 9,12,14,19},
{ 11, 23,28,31,35,37,42},
{ 12, 25,34,37,40,45,48},
{ 13, 32,33,44,46,47,48},
{ 14, 24,25,26,27,37,48},
{ 15, 24,29,30,32,40,42},
{ 16, 1, 3, 6,10,15,19},
{ 17, 1, 3, 7,11,14,18},
{ 18, 22,23,25,35,42,43},
{ 19, 1, 3, 8,12,17,21},
{ 20, 31,33,34,40,43,45},
{ 21, 30,33,36,39,44,48},
{ 22, 25,29,37,38,41,48},
{ 23, 1, 3, 9,13,16,20},
{ 24, 1, 4, 6,13,14,21},
{ 25, 24,25,28,33,41,45},
{ 26, 22,26,31,38,40,48},
{ 27, 1, 4, 7,12,15,20},
{ 28, 24,26,27,31,33,43},
{ 29, 23,27,32,39,40,41},
{ 30, 1, 4, 8,11,16,19},
{ 31, 22,25,32,43,46,47},
{ 32, 22,33,37,39,42,47},
{ 33, 1, 4, 9,10,17,18},
{ 34, 27,35,38,39,45,46},
{ 35, 1, 5, 6,12,16,18},
{ 36, 1, 5, 7,13,17,19},
{ 37, 1, 5, 8,10,14,20},
{ 38, 1, 5, 9,11,15,21},
{ 39, 1, 6, 7, 8, 9,49},
{ 40, 26,29,36,42,45,46},
{ 41, 1,10,11,12,13,49},
{ 42, 1,14,15,16,17,49},
{ 43, 1,18,19,20,21,49},
{ 44, 28,31,32,37,46,47},
{ 45, 22,25,30,36,39,43},
{ 46, 24,37,41,43,44,45},
{ 47, 26,34,35,39,41,46},
{ 48, 27,30,32,38,42,45},
{ 49, 22,24,26,27,28,44},
{ 50, 23,24,32,34,38,39},
{ 51, 22,32,33,35,36,37},
{ 52, 22,28,29,38,41,44},
{ 53, 28,39,42,43,47,48},
{ 54, 27,30,35,40,41,47},
{ 55, 2, 3, 6, 7,12,13},
{ 56, 27,36,40,41,42,46},
{ 57, 2, 3, 8, 9,10,11},
{ 58, 28,30,31,36,37,39},
{ 59, 2, 3,14,15,20,21},
{ 60, 23,24,29,36,40,47},
{ 61, 29,31,33,38,41,43},
{ 62, 2, 3,16,17,18,19},
{ 63, 26,29,30,35,45,47},
{ 64, 22,25,27,29,34,43},
{ 65, 2, 4, 6, 9,15,16},
{ 66, 26,37,38,40,43,44},
{ 67, 26,30,32,34,41,42},
{ 68, 23,30,31,33,43,46},
{ 69, 25,31,35,39,44,47},
{ 70, 2, 4, 7, 8,14,17},
{ 71, 2, 4,10,13,19,20},
{ 72, 2, 4,11,12,18,21},
{ 73, 24,34,36,38,42,46},
{ 74, 2, 5, 6, 8,19,21},
{ 75, 2, 5, 7, 9,18,20},
{ 76, 22,24,31,41,45,48},
{ 77, 25,26,28,33,38,40},
{ 78, 2, 5,10,12,15,17},
{ 79, 2, 5,11,13,14,16},
{ 80, 2, 6,10,14,18,49},
{ 81, 2, 7,11,15,19,49},
{ 82, 2, 8,12,16,20,49},
{ 83, 2, 9,13,17,21,49},
{ 84, 23,26,29,32,39,45},
{ 85, 24,30,34,35,38,47},
{ 86, 3, 4, 6, 8,18,20},
{ 87, 3, 4, 7, 9,19,21},
{ 88, 3, 4,10,12,14,16},
{ 89, 3, 4,11,13,15,17},
{ 90, 3, 5, 6, 9,14,17},
{ 91, 3, 5, 7, 8,15,16},
{ 92, 27,28,29,31,34,37},
{ 93, 23,25,30,37,46,48},
{ 94, 3, 5,10,13,18,21},
{ 95, 3, 5,11,12,19,20},
{ 96, 3, 6,11,16,21,49},
{ 97, 3, 7,10,17,20,49},
{ 98, 6, 7,14,16,19,20},
{ 99, 3, 8,13,14,19,49},
{100, 3, 9,12,15,18,49},
{101, 6, 7,15,17,18,21},
{102, 6, 8,10,13,16,17},
{103, 6, 8,11,12,14,15},
{104, 6, 9,10,12,20,21},
{105, 6, 9,11,13,18,19},
{106, 25,31,32,35,36,44},
{107, 4, 5, 8, 9,12,13},
{108, 4, 5,14,15,18,19},
{109, 4, 5,16,17,20,21},
{110, 4, 6,12,17,19,49},
{111, 4, 7,13,16,18,49},
{112, 7, 8,10,12,18,19},
{113, 7, 8,11,13,20,21},
{114, 7, 9,10,13,14,15},
{115, 7, 9,11,12,16,17},
{116, 8, 9,14,16,18,21},
{117, 8, 9,15,17,19,20},
{118, 10,11,14,17,19,21},
{119, 10,11,15,16,18,20},
{120, 12,13,14,17,18,20},
{121, 12,13,15,16,19,21},
{122, 4, 8,10,15,21,49},
{123, 4, 9,11,14,20,49},
{124, 5, 6,13,15,20,49},
{125, 5, 7,12,14,21,49},
{126, 5, 8,11,17,18,49},
{127, 5, 9,10,16,19,49},
{128, 4, 5, 6, 7,10,11},
{129, 22,23,28,30,44,46},
{130, 27,29,33,34,44,48},
{131, 28,32,36,42,43,48},
{132, 25,26,31,40,41,44},
{133, 24,28,38,40,43,48},
{134, 28,35,36,43,47,48},
{135, 24,25,31,38,44,45},
{136, 26,28,41,43,45,48},
{137, 25,28,29,33,44,46},
{138, 27,30,31,37,43,44},
{139, 22,23,25,31,34,48},
{140, 23,25,27,28,33,37},
{141, 22,29,30,31,33,48},
{142, 22,34,37,43,44,46},
{143, 25,31,36,42,44,47},
{144, 38,39,40,41,42,47},
{145, 22,26,33,37,38,45},
{146, 24,27,34,39,42,47},
{147, 23,26,32,35,42,45},
{148, 28,32,35,39,43,48},
{149, 23,29,37,43,44,48},
{150, 22,27,28,31,46,48},
{151, 22,24,33,37,40,41},
{152, 25,28,30,33,34,43},
{153, 23,30,34,38,40,46},
{154, 26,30,32,36,39,45},
{155, 27,29,34,35,38,41},
{156, 26,29,32,45,46,47},
{157, 23,24,27,30,41,46},
{158, 23,29,30,36,39,42},
{159, 25,31,32,39,42,44},
{160, 24,32,35,36,38,41},
{161, 24,26,27,29,40,45},
{162, 27,32,34,35,36,40},
{163, 23,30,35,36,46,47}};

for (int lpcnt = 1; lpcnt <= GlobalValues.kNoSeconds; lpcnt++)
GlobalValues.gaSumWorkDays[lpcnt] = 0;

for (int mm = 1; mm <= GlobalValues.kNoDays; mm++)
{
GlobalValues.gaWorkDays[1] = TimeSchedule[mm, 1];
GlobalValues.gaWorkDays[2] = TimeSchedule[mm, 2];
GlobalValues.gaWorkDays[3] = TimeSchedule[mm, 3];
GlobalValues.gaWorkDays[4] = TimeSchedule[mm, 4];
GlobalValues.gaWorkDays[5] = TimeSchedule[mm, 5];
GlobalValues.gaWorkDays[6] = TimeSchedule[mm, 6];
CWeekTime.WeekTime();
}
int lnTotMissingTime = 0;

DateTime start = DateTime.Now;

//Create gaSeconds2 from gaSeconds
for (int i = 0; i < GlobalValues.gaSeconds2.Length; i++)
{
GlobalValues.gaSeconds2[i] = new int[4];
for (int j = 0; j < 4; j++)
GlobalValues.gaSeconds2[i][j] =
GlobalValues.gaSeconds[i, j];
}

lnTotMissingTime = CVerifyMissingTime.VerifyMissingTime();
Console.WriteLine("Total No of Missing Time {0} ",
lnTotMissingTime);

Console.WriteLine(DateTime.Now-start);

Console.ReadLine();

return 0;

}
}

public class GlobalValues
{
public static int[][] gaSeconds2 = new int[kNoWeeks +1][];
public const int kNoWeeks = 49;
public const int kNoDays = 163;
public const int kNoSeconds = 18424;
public static int gnSumSeconds = 0;
public static int[] gaWorkDays = new int[7];
public static int[] gaSumWorkDays = new int[kNoSeconds + 1];

public static int[,] gaSeconds = new int[kNoWeeks + 1, 4]
{
{0, 0, 0, 0},
{1, 0, 0, 0},
{2, 1081, 0, 0},
{3, 2116, 46, 1},
{4, 3106, 91, 2},
{5, 4052, 135, 3},
{6, 4955, 178, 4},
{7, 5816, 220, 5},
{8, 6636, 261, 6},
{9, 7416, 301, 7},
{10, 8157, 340, 8},
{11, 8860, 378, 9},
{12, 9526, 415, 10},
{13, 10156, 451, 11},
{14, 10751, 486, 12},
{15, 11312, 520, 13},
{16, 11840, 553, 14},
{17, 12336, 585, 15},
{18, 12801, 616, 16},
{19, 13236, 646, 17},
{20, 13642, 675, 18},
{21, 14020, 703, 19},
{22, 14371, 730, 20},
{23, 14696, 756, 21},
{24, 14996, 781, 22},
{25, 15272, 805, 23},
{26, 15525, 828, 24},
{27, 15756, 850, 25},
{28, 15966, 871, 26},
{29, 16156, 891, 27},
{30, 16327, 910, 28},
{31, 16480, 928, 29},
{32, 16616, 945, 30},
{33, 16736, 961, 31},
{34, 16841, 976, 32},
{35, 16932, 990, 33},
{36, 17010, 1003, 34},
{37, 17076, 1015, 35},
{38, 17131, 1026, 36},
{39, 17176, 1036, 37},
{40, 17212, 1045, 38},
{41, 17240, 1053, 39},
{42, 17261, 1060, 40},
{43, 17276, 1066, 41},
{44, 17286, 1071, 42},
{45, 17292, 1075, 43},
{46, 17295, 1078, 44},
{47, 17296, 1080, 45},
{48, 0, 1081, 46},
{49, 0, 0, 47}};
}

class CWeekTime
{
public static int WeekTime()
{
for (int s1 = 1; s1 <= 4; s1++)
{
for (int s2 = s1 + 1; s2 <= 5; s2++)
{
for (int s3 = s2 + 1; s3 <= 6; s3++)
{
GlobalValues.gnSumSeconds =
GlobalValues.gaSeconds[GlobalValues.gaWorkDays[s1], 1] +
GlobalValues.gaSeconds[GlobalValues.gaWorkDays[s2], 2] +
GlobalValues.gaSeconds[GlobalValues.gaWorkDays[s3], 3];

GlobalValues.gaSumWorkDays[GlobalValues.gnSumSeconds] = 1;
}
}
}
return (0);
}
}

class CVerifyMissingTime
{
public static int VerifyMissingTime()
{
int lnSumMissingTime = 0;

for (int xxxLoop = 1; xxxLoop <= 10; xxxLoop++)
{
lnSumMissingTime = 0;

for (int lp1 = 1; lp1 <= GlobalValues.kNoWeeks - 5; lp1++)
{
int lp11 = GlobalValues.gaSeconds2[lp1][1];

for (int lp2 = lp1 + 1; lp2 <= GlobalValues.kNoWeeks -
4; lp2++)
{
int lp21 = GlobalValues.gaSeconds2[lp2][1];
int lp22 = GlobalValues.gaSeconds2[lp2][2];
//(lp2 <= 2 || lp2 == 49) ? 0 : (lp2 - 2) * (95 - lp2) / 2;
//Lookup is faster

for (int lp3 = lp2 + 1; lp3 <=
GlobalValues.kNoWeeks - 3; lp3++)
{
int lp31 = GlobalValues.gaSeconds2[lp3][1];
int lp32 = GlobalValues.gaSeconds2[lp3][2];
int lp33 = GlobalValues.gaSeconds2[lp3][3];

for (int lp4 = lp3 + 1; lp4 <=
GlobalValues.kNoWeeks - 2; lp4++)
{
int lp41 =
GlobalValues.gaSeconds2[lp4][1];
int lp42 =
GlobalValues.gaSeconds2[lp4][2];
int lp43 =
GlobalValues.gaSeconds2[lp4][3];

for (int lp5 = lp4 + 1; lp5 <=
GlobalValues.kNoWeeks - 1; lp5++)
{
int lp52 =
GlobalValues.gaSeconds2[lp5][2];
int lp53 =
GlobalValues.gaSeconds2[lp5][3];

for (int lp6 = lp5 + 1; lp6 <=
GlobalValues.kNoWeeks; lp6++)
{
if (

GlobalValues.gaSumWorkDays[lp11 + lp22 + lp33] > 0)
{
goto breakOut4;
}
else if (

(GlobalValues.gaSumWorkDays[lp11 + lp22 + lp43] > 0)
||

(GlobalValues.gaSumWorkDays[lp11 + lp32 + lp43] > 0)
||

(GlobalValues.gaSumWorkDays[lp21 + lp32 + lp43] > 0))
{
goto breakOut5;
}

if (

(GlobalValues.gaSumWorkDays[lp11 + lp22 + lp53] > 0)
||

(GlobalValues.gaSumWorkDays[lp11 + lp32 + lp53] > 0)
||

(GlobalValues.gaSumWorkDays[lp11 + lp42 + lp53] > 0)
||

(GlobalValues.gaSumWorkDays[lp21 + lp32 + lp53] > 0)
||

(GlobalValues.gaSumWorkDays[lp21 + lp42 + lp53] > 0)
||

(GlobalValues.gaSumWorkDays[lp31 + lp42 + lp53] > 0))
{
break;
}

int lp63 =
GlobalValues.gaSeconds2[lp6][3];

if (
(GlobalValues.gaSumWorkDays[lp11 +
lp22 + lp63] > 0)
||
(GlobalValues.gaSumWorkDays[lp11 +
lp32 + lp63] > 0)
||
(GlobalValues.gaSumWorkDays[lp11 +
lp42 + lp63] > 0)
||
(GlobalValues.gaSumWorkDays[lp11 +
lp52 + lp63] > 0)
||
(GlobalValues.gaSumWorkDays[lp21 +
lp32 + lp63] > 0)
||
(GlobalValues.gaSumWorkDays[lp21 +
lp42 + lp63] > 0)
||
(GlobalValues.gaSumWorkDays[lp21 +
lp52 + lp63] > 0)
||
(GlobalValues.gaSumWorkDays[lp31 +
lp42 + lp63] > 0)
||
(GlobalValues.gaSumWorkDays[lp31 +
lp52 + lp63] > 0)
||
(GlobalValues.gaSumWorkDays[lp41 +
lp52 + lp63] > 0))
{
continue;
}

lnSumMissingTime++;

}
}
breakOut5: ;
}
breakOut4: ;
}
}
}
}
Console.WriteLine("Missing Time {0}", lnSumMissingTime);

return lnSumMissingTime;

}
}

--
Marcus Andrén
Nov 17 '05 #5

P: n/a
Hi Marcus,

WOW that is good indeed. That is even faster than the time I was getting in
C++. :) I am not that good at C++ either, mind you. :)

But I do not understand how you got it to be so much faster, as it is now
about 6 times faster than before. Where is most of the time gain coming
from? I will try to disect what you did and also try to apply it to my C++
program.

Finally, I don't understand what you mean by making gaSeconds jagged at the
beginning and then changing it to multidimensional in the rest of the
program. How would that be done?

Thanks a lot, I appreciate it.

Roy
"Marcus Andrén" <a@b.c> wrote in message
news:vd********************************@4ax.com...
On Sun, 9 Oct 2005 10:39:09 +0100, "Roy Gourgi" <ro***@videotron.ca>
wrote:
Hi,

I am new to C#. I have the same time scheduling program written in C++ and
it is 5 times faster than my version in C#.
Why is it so slow as I thought that C# was only a little slower than C++?
What am I doing wrong?


First of all, in my experience c# isn't very good at handling multi
level loops so don't expect to ever get C++ performance with an
algorithm like that with the current c# compiler.

I can see a few ways of optimizing the code. The big winner as Jon
Skeet already suggested is to used make gaSeconsds jagged instead of
multidimensional. Even if it has to be multidimensional in the rest of
the program it will still pay off to convert it to jagged formet
before doing the calculations. This is the best way to increase
performance and will almost half the running time.

You recalculate quite a few of the array accesses multiple times. They
could be calculated and stored in local variables in the outer for
loops.

Finally replacing lp6=100; continue; with break; will give a small
performance boost.
Here is a rewrite of your code that runs a lot faster:
using System;

class cMain
{
public static int Main()
{
int[,] TimeSchedule = new int[GlobalValues.kNoDays + 1, 7]
{
{ 0, 0, 0, 0, 0, 0, 0},
{ 1, 1, 2, 3, 4, 5,49},
{ 2, 23,27,36,38,45,47},
{ 3, 23,33,35,42,44,48},
{ 4, 24,29,35,39,40,46},
{ 5, 22,28,34,40,44,45},
{ 6, 1, 2, 6,11,17,20},
{ 7, 1, 2, 7,10,16,21},
{ 8, 1, 2, 8,13,15,18},
{ 9, 23,26,34,36,41,47},
{ 10, 1, 2, 9,12,14,19},
{ 11, 23,28,31,35,37,42},
{ 12, 25,34,37,40,45,48},
{ 13, 32,33,44,46,47,48},
{ 14, 24,25,26,27,37,48},
{ 15, 24,29,30,32,40,42},
{ 16, 1, 3, 6,10,15,19},
{ 17, 1, 3, 7,11,14,18},
{ 18, 22,23,25,35,42,43},
{ 19, 1, 3, 8,12,17,21},
{ 20, 31,33,34,40,43,45},
{ 21, 30,33,36,39,44,48},
{ 22, 25,29,37,38,41,48},
{ 23, 1, 3, 9,13,16,20},
{ 24, 1, 4, 6,13,14,21},
{ 25, 24,25,28,33,41,45},
{ 26, 22,26,31,38,40,48},
{ 27, 1, 4, 7,12,15,20},
{ 28, 24,26,27,31,33,43},
{ 29, 23,27,32,39,40,41},
{ 30, 1, 4, 8,11,16,19},
{ 31, 22,25,32,43,46,47},
{ 32, 22,33,37,39,42,47},
{ 33, 1, 4, 9,10,17,18},
{ 34, 27,35,38,39,45,46},
{ 35, 1, 5, 6,12,16,18},
{ 36, 1, 5, 7,13,17,19},
{ 37, 1, 5, 8,10,14,20},
{ 38, 1, 5, 9,11,15,21},
{ 39, 1, 6, 7, 8, 9,49},
{ 40, 26,29,36,42,45,46},
{ 41, 1,10,11,12,13,49},
{ 42, 1,14,15,16,17,49},
{ 43, 1,18,19,20,21,49},
{ 44, 28,31,32,37,46,47},
{ 45, 22,25,30,36,39,43},
{ 46, 24,37,41,43,44,45},
{ 47, 26,34,35,39,41,46},
{ 48, 27,30,32,38,42,45},
{ 49, 22,24,26,27,28,44},
{ 50, 23,24,32,34,38,39},
{ 51, 22,32,33,35,36,37},
{ 52, 22,28,29,38,41,44},
{ 53, 28,39,42,43,47,48},
{ 54, 27,30,35,40,41,47},
{ 55, 2, 3, 6, 7,12,13},
{ 56, 27,36,40,41,42,46},
{ 57, 2, 3, 8, 9,10,11},
{ 58, 28,30,31,36,37,39},
{ 59, 2, 3,14,15,20,21},
{ 60, 23,24,29,36,40,47},
{ 61, 29,31,33,38,41,43},
{ 62, 2, 3,16,17,18,19},
{ 63, 26,29,30,35,45,47},
{ 64, 22,25,27,29,34,43},
{ 65, 2, 4, 6, 9,15,16},
{ 66, 26,37,38,40,43,44},
{ 67, 26,30,32,34,41,42},
{ 68, 23,30,31,33,43,46},
{ 69, 25,31,35,39,44,47},
{ 70, 2, 4, 7, 8,14,17},
{ 71, 2, 4,10,13,19,20},
{ 72, 2, 4,11,12,18,21},
{ 73, 24,34,36,38,42,46},
{ 74, 2, 5, 6, 8,19,21},
{ 75, 2, 5, 7, 9,18,20},
{ 76, 22,24,31,41,45,48},
{ 77, 25,26,28,33,38,40},
{ 78, 2, 5,10,12,15,17},
{ 79, 2, 5,11,13,14,16},
{ 80, 2, 6,10,14,18,49},
{ 81, 2, 7,11,15,19,49},
{ 82, 2, 8,12,16,20,49},
{ 83, 2, 9,13,17,21,49},
{ 84, 23,26,29,32,39,45},
{ 85, 24,30,34,35,38,47},
{ 86, 3, 4, 6, 8,18,20},
{ 87, 3, 4, 7, 9,19,21},
{ 88, 3, 4,10,12,14,16},
{ 89, 3, 4,11,13,15,17},
{ 90, 3, 5, 6, 9,14,17},
{ 91, 3, 5, 7, 8,15,16},
{ 92, 27,28,29,31,34,37},
{ 93, 23,25,30,37,46,48},
{ 94, 3, 5,10,13,18,21},
{ 95, 3, 5,11,12,19,20},
{ 96, 3, 6,11,16,21,49},
{ 97, 3, 7,10,17,20,49},
{ 98, 6, 7,14,16,19,20},
{ 99, 3, 8,13,14,19,49},
{100, 3, 9,12,15,18,49},
{101, 6, 7,15,17,18,21},
{102, 6, 8,10,13,16,17},
{103, 6, 8,11,12,14,15},
{104, 6, 9,10,12,20,21},
{105, 6, 9,11,13,18,19},
{106, 25,31,32,35,36,44},
{107, 4, 5, 8, 9,12,13},
{108, 4, 5,14,15,18,19},
{109, 4, 5,16,17,20,21},
{110, 4, 6,12,17,19,49},
{111, 4, 7,13,16,18,49},
{112, 7, 8,10,12,18,19},
{113, 7, 8,11,13,20,21},
{114, 7, 9,10,13,14,15},
{115, 7, 9,11,12,16,17},
{116, 8, 9,14,16,18,21},
{117, 8, 9,15,17,19,20},
{118, 10,11,14,17,19,21},
{119, 10,11,15,16,18,20},
{120, 12,13,14,17,18,20},
{121, 12,13,15,16,19,21},
{122, 4, 8,10,15,21,49},
{123, 4, 9,11,14,20,49},
{124, 5, 6,13,15,20,49},
{125, 5, 7,12,14,21,49},
{126, 5, 8,11,17,18,49},
{127, 5, 9,10,16,19,49},
{128, 4, 5, 6, 7,10,11},
{129, 22,23,28,30,44,46},
{130, 27,29,33,34,44,48},
{131, 28,32,36,42,43,48},
{132, 25,26,31,40,41,44},
{133, 24,28,38,40,43,48},
{134, 28,35,36,43,47,48},
{135, 24,25,31,38,44,45},
{136, 26,28,41,43,45,48},
{137, 25,28,29,33,44,46},
{138, 27,30,31,37,43,44},
{139, 22,23,25,31,34,48},
{140, 23,25,27,28,33,37},
{141, 22,29,30,31,33,48},
{142, 22,34,37,43,44,46},
{143, 25,31,36,42,44,47},
{144, 38,39,40,41,42,47},
{145, 22,26,33,37,38,45},
{146, 24,27,34,39,42,47},
{147, 23,26,32,35,42,45},
{148, 28,32,35,39,43,48},
{149, 23,29,37,43,44,48},
{150, 22,27,28,31,46,48},
{151, 22,24,33,37,40,41},
{152, 25,28,30,33,34,43},
{153, 23,30,34,38,40,46},
{154, 26,30,32,36,39,45},
{155, 27,29,34,35,38,41},
{156, 26,29,32,45,46,47},
{157, 23,24,27,30,41,46},
{158, 23,29,30,36,39,42},
{159, 25,31,32,39,42,44},
{160, 24,32,35,36,38,41},
{161, 24,26,27,29,40,45},
{162, 27,32,34,35,36,40},
{163, 23,30,35,36,46,47}};

for (int lpcnt = 1; lpcnt <= GlobalValues.kNoSeconds; lpcnt++)
GlobalValues.gaSumWorkDays[lpcnt] = 0;

for (int mm = 1; mm <= GlobalValues.kNoDays; mm++)
{
GlobalValues.gaWorkDays[1] = TimeSchedule[mm, 1];
GlobalValues.gaWorkDays[2] = TimeSchedule[mm, 2];
GlobalValues.gaWorkDays[3] = TimeSchedule[mm, 3];
GlobalValues.gaWorkDays[4] = TimeSchedule[mm, 4];
GlobalValues.gaWorkDays[5] = TimeSchedule[mm, 5];
GlobalValues.gaWorkDays[6] = TimeSchedule[mm, 6];
CWeekTime.WeekTime();
}
int lnTotMissingTime = 0;

DateTime start = DateTime.Now;

//Create gaSeconds2 from gaSeconds
for (int i = 0; i < GlobalValues.gaSeconds2.Length; i++)
{
GlobalValues.gaSeconds2[i] = new int[4];
for (int j = 0; j < 4; j++)
GlobalValues.gaSeconds2[i][j] =
GlobalValues.gaSeconds[i, j];
}

lnTotMissingTime = CVerifyMissingTime.VerifyMissingTime();
Console.WriteLine("Total No of Missing Time {0} ",
lnTotMissingTime);

Console.WriteLine(DateTime.Now-start);

Console.ReadLine();

return 0;

}
}

public class GlobalValues
{
public static int[][] gaSeconds2 = new int[kNoWeeks +1][];
public const int kNoWeeks = 49;
public const int kNoDays = 163;
public const int kNoSeconds = 18424;
public static int gnSumSeconds = 0;
public static int[] gaWorkDays = new int[7];
public static int[] gaSumWorkDays = new int[kNoSeconds + 1];

public static int[,] gaSeconds = new int[kNoWeeks + 1, 4]
{
{0, 0, 0, 0},
{1, 0, 0, 0},
{2, 1081, 0, 0},
{3, 2116, 46, 1},
{4, 3106, 91, 2},
{5, 4052, 135, 3},
{6, 4955, 178, 4},
{7, 5816, 220, 5},
{8, 6636, 261, 6},
{9, 7416, 301, 7},
{10, 8157, 340, 8},
{11, 8860, 378, 9},
{12, 9526, 415, 10},
{13, 10156, 451, 11},
{14, 10751, 486, 12},
{15, 11312, 520, 13},
{16, 11840, 553, 14},
{17, 12336, 585, 15},
{18, 12801, 616, 16},
{19, 13236, 646, 17},
{20, 13642, 675, 18},
{21, 14020, 703, 19},
{22, 14371, 730, 20},
{23, 14696, 756, 21},
{24, 14996, 781, 22},
{25, 15272, 805, 23},
{26, 15525, 828, 24},
{27, 15756, 850, 25},
{28, 15966, 871, 26},
{29, 16156, 891, 27},
{30, 16327, 910, 28},
{31, 16480, 928, 29},
{32, 16616, 945, 30},
{33, 16736, 961, 31},
{34, 16841, 976, 32},
{35, 16932, 990, 33},
{36, 17010, 1003, 34},
{37, 17076, 1015, 35},
{38, 17131, 1026, 36},
{39, 17176, 1036, 37},
{40, 17212, 1045, 38},
{41, 17240, 1053, 39},
{42, 17261, 1060, 40},
{43, 17276, 1066, 41},
{44, 17286, 1071, 42},
{45, 17292, 1075, 43},
{46, 17295, 1078, 44},
{47, 17296, 1080, 45},
{48, 0, 1081, 46},
{49, 0, 0, 47}};
}

class CWeekTime
{
public static int WeekTime()
{
for (int s1 = 1; s1 <= 4; s1++)
{
for (int s2 = s1 + 1; s2 <= 5; s2++)
{
for (int s3 = s2 + 1; s3 <= 6; s3++)
{
GlobalValues.gnSumSeconds =
GlobalValues.gaSeconds[GlobalValues.gaWorkDays[s1], 1] +
GlobalValues.gaSeconds[GlobalValues.gaWorkDays[s2], 2] +
GlobalValues.gaSeconds[GlobalValues.gaWorkDays[s3], 3];

GlobalValues.gaSumWorkDays[GlobalValues.gnSumSeconds] = 1;
}
}
}
return (0);
}
}

class CVerifyMissingTime
{
public static int VerifyMissingTime()
{
int lnSumMissingTime = 0;

for (int xxxLoop = 1; xxxLoop <= 10; xxxLoop++)
{
lnSumMissingTime = 0;

for (int lp1 = 1; lp1 <= GlobalValues.kNoWeeks - 5; lp1++)
{
int lp11 = GlobalValues.gaSeconds2[lp1][1];

for (int lp2 = lp1 + 1; lp2 <= GlobalValues.kNoWeeks -
4; lp2++)
{
int lp21 = GlobalValues.gaSeconds2[lp2][1];
int lp22 = GlobalValues.gaSeconds2[lp2][2];
//(lp2 <= 2 || lp2 == 49) ? 0 : (lp2 - 2) * (95 - lp2) / 2;
//Lookup is faster

for (int lp3 = lp2 + 1; lp3 <=
GlobalValues.kNoWeeks - 3; lp3++)
{
int lp31 = GlobalValues.gaSeconds2[lp3][1];
int lp32 = GlobalValues.gaSeconds2[lp3][2];
int lp33 = GlobalValues.gaSeconds2[lp3][3];

for (int lp4 = lp3 + 1; lp4 <=
GlobalValues.kNoWeeks - 2; lp4++)
{
int lp41 =
GlobalValues.gaSeconds2[lp4][1];
int lp42 =
GlobalValues.gaSeconds2[lp4][2];
int lp43 =
GlobalValues.gaSeconds2[lp4][3];

for (int lp5 = lp4 + 1; lp5 <=
GlobalValues.kNoWeeks - 1; lp5++)
{
int lp52 =
GlobalValues.gaSeconds2[lp5][2];
int lp53 =
GlobalValues.gaSeconds2[lp5][3];

for (int lp6 = lp5 + 1; lp6 <=
GlobalValues.kNoWeeks; lp6++)
{
if (

GlobalValues.gaSumWorkDays[lp11 + lp22 + lp33] > 0)
{
goto breakOut4;
}
else if (

(GlobalValues.gaSumWorkDays[lp11 + lp22 + lp43] > 0)
||

(GlobalValues.gaSumWorkDays[lp11 + lp32 + lp43] > 0)
||

(GlobalValues.gaSumWorkDays[lp21 + lp32 + lp43] > 0))
{
goto breakOut5;
}

if (

(GlobalValues.gaSumWorkDays[lp11 + lp22 + lp53] > 0)
||

(GlobalValues.gaSumWorkDays[lp11 + lp32 + lp53] > 0)
||

(GlobalValues.gaSumWorkDays[lp11 + lp42 + lp53] > 0)
||

(GlobalValues.gaSumWorkDays[lp21 + lp32 + lp53] > 0)
||

(GlobalValues.gaSumWorkDays[lp21 + lp42 + lp53] > 0)
||

(GlobalValues.gaSumWorkDays[lp31 + lp42 + lp53] > 0))
{
break;
}

int lp63 =
GlobalValues.gaSeconds2[lp6][3];

if (
(GlobalValues.gaSumWorkDays[lp11 +
lp22 + lp63] > 0)
||
(GlobalValues.gaSumWorkDays[lp11 +
lp32 + lp63] > 0)
||
(GlobalValues.gaSumWorkDays[lp11 +
lp42 + lp63] > 0)
||
(GlobalValues.gaSumWorkDays[lp11 +
lp52 + lp63] > 0)
||
(GlobalValues.gaSumWorkDays[lp21 +
lp32 + lp63] > 0)
||
(GlobalValues.gaSumWorkDays[lp21 +
lp42 + lp63] > 0)
||
(GlobalValues.gaSumWorkDays[lp21 +
lp52 + lp63] > 0)
||
(GlobalValues.gaSumWorkDays[lp31 +
lp42 + lp63] > 0)
||
(GlobalValues.gaSumWorkDays[lp31 +
lp52 + lp63] > 0)
||
(GlobalValues.gaSumWorkDays[lp41 +
lp52 + lp63] > 0))
{
continue;
}

lnSumMissingTime++;

}
}
breakOut5: ;
}
breakOut4: ;
}
}
}
}
Console.WriteLine("Missing Time {0}", lnSumMissingTime);

return lnSumMissingTime;

}
}

--
Marcus Andrén

Nov 17 '05 #6

P: n/a
Roy Gourgi <ro***@videotron.ca> wrote:
Basically, for all intensive purposes all I have is 2 arrays (gaSeconds &
TimeSchedule). The array gaSeconds as you can see, has to be accessed many,
many times and for this application, it cannot absolutely be a jagged array.
Why not, out of interest?
The values in the gaSeconds in the real application change, but I kept them
constant for the sake of simplicity, so although it looks that I am
aimlessly accessing the same information many times in the
CVerifyMissingTime, I am not.

All I wanted to know if there is a way to make this faster. I am not that
worried about wheter it is in classic object oriented programming form as
speed is of the essence.


In my experience, it's much easier to change something to be faster
when it's clear what it's doing.

I'm glad Marcus has managed to improve the speed for you, but I really
would try re-writing it in an OO way and looking at it after that.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Nov 17 '05 #7

P: n/a
On Sun, 9 Oct 2005 19:20:40 +0100, "Roy Gourgi" <ro***@videotron.ca>
wrote:
Hi Marcus,

WOW that is good indeed. That is even faster than the time I was getting in
C++. :) I am not that good at C++ either, mind you. :)

But I do not understand how you got it to be so much faster, as it is now
about 6 times faster than before. Where is most of the time gain coming
from? I will try to disect what you did and also try to apply it to my C++
program.


I only getting about a 2-3 times gain on my computer.The gain comes
from three sources. The biggest being to used a jagged array instead
of a multidimensional one. The second biggest is to move array access
to the outer for loops like this.

int lp31 = GlobalValues.gaSeconds2[lp3][1];

No need to recalculate the values each loop and the compiler is
unfortunally not smart enough to realize by itself that it doesn't
have to. The third improvement was minor. It was to replace
lp6=100;continue; with just break;.

I also replaced lp5=lp6=100;continue; with goto breakOut5; and
lp4=lp5=lp6=100;continue; with goto breakOut4; because even though
goto is a statement to be avoided in most cases it is in my opinion
much worse to change loop indexes to break out of a loop.

I also combined a bunch of comparisons into a single if statement if
they had the same outcome. It didn't give any performance boost, but
it makes the look much code more structured.

Ok, I just came up with an idea and looked at your code again. goto
and break aren't needed at all. A lot of the comparisons can be moved
to outer loops and use continue; instead. It will speed up the code
considerably. After this modification I don't think there is much more
that can be done. Here is the modified version of VerifyMissingTime():

public static int VerifyMissingTime()
{
int lnSumMissingTime = 0;

for (int xxxLoop = 1; xxxLoop <= 10; xxxLoop++)
{
lnSumMissingTime = 0;

for (int lp1 = 1; lp1 <= GlobalValues.kNoWeeks - 5; lp1++)
{
int lp11 = GlobalValues.gaSeconds2[lp1][1];

for (int lp2 = lp1 + 1; lp2 <= GlobalValues.kNoWeeks -
4; lp2++)
{
int lp21 = GlobalValues.gaSeconds2[lp2][1];
int lp22 = GlobalValues.gaSeconds2[lp2][2];
//(lp2 <= 2 || lp2 == 49) ? 0 : (lp2 - 2) * (95 - lp2) / 2;
//Lookup is faster

for (int lp3 = lp2 + 1; lp3 <=
GlobalValues.kNoWeeks - 3; lp3++)
{
int lp31 = GlobalValues.gaSeconds2[lp3][1];
int lp32 = GlobalValues.gaSeconds2[lp3][2];
int lp33 = GlobalValues.gaSeconds2[lp3][3];

if (GlobalValues.gaSumWorkDays[lp11 + lp22 +
lp33] > 0)
continue;

for (int lp4 = lp3 + 1; lp4 <=
GlobalValues.kNoWeeks - 2; lp4++)
{
int lp41 =
GlobalValues.gaSeconds2[lp4][1];
int lp42 =
GlobalValues.gaSeconds2[lp4][2];
int lp43 =
GlobalValues.gaSeconds2[lp4][3];

if ((GlobalValues.gaSumWorkDays[lp11 +
lp22 + lp43] > 0)
||
(GlobalValues.gaSumWorkDays[lp11 +
lp32 + lp43] > 0)
||
(GlobalValues.gaSumWorkDays[lp21 +
lp32 + lp43] > 0))
{
continue;
}
for (int lp5 = lp4 + 1; lp5 <=
GlobalValues.kNoWeeks - 1; lp5++)
{
int lp52 =
GlobalValues.gaSeconds2[lp5][2];
int lp53 =
GlobalValues.gaSeconds2[lp5][3];

if (
(GlobalValues.gaSumWorkDays[lp11 +
lp22 + lp53] > 0)
||
(GlobalValues.gaSumWorkDays[lp11 +
lp32 + lp53] > 0)
||
(GlobalValues.gaSumWorkDays[lp11 +
lp42 + lp53] > 0)
||
(GlobalValues.gaSumWorkDays[lp21 +
lp32 + lp53] > 0)
||
(GlobalValues.gaSumWorkDays[lp21 +
lp42 + lp53] > 0)
||
(GlobalValues.gaSumWorkDays[lp31 +
lp42 + lp53] > 0))
{
continue;
}

for (int lp6 = lp5 + 1; lp6 <=
GlobalValues.kNoWeeks; lp6++)
{

int lp63 =
GlobalValues.gaSeconds2[lp6][3];

if (

(GlobalValues.gaSumWorkDays[lp11 + lp22 + lp63] > 0)
||

(GlobalValues.gaSumWorkDays[lp11 + lp32 + lp63] > 0)
||

(GlobalValues.gaSumWorkDays[lp11 + lp42 + lp63] > 0)
||

(GlobalValues.gaSumWorkDays[lp11 + lp52 + lp63] > 0)
||

(GlobalValues.gaSumWorkDays[lp21 + lp32 + lp63] > 0)
||

(GlobalValues.gaSumWorkDays[lp21 + lp42 + lp63] > 0)
||

(GlobalValues.gaSumWorkDays[lp21 + lp52 + lp63] > 0)
||

(GlobalValues.gaSumWorkDays[lp31 + lp42 + lp63] > 0)
||

(GlobalValues.gaSumWorkDays[lp31 + lp52 + lp63] > 0)
||

(GlobalValues.gaSumWorkDays[lp41 + lp52 + lp63] > 0))
{
continue;
}

lnSumMissingTime++;
}
}
}
}
}
}
}
Console.WriteLine("Missing Time {0}", lnSumMissingTime);

return lnSumMissingTime;
}



--
Marcus Andrén
Nov 17 '05 #8

P: n/a
Roy,

I have looked at your program and I cannot truly figure out what you are doing.
I see names like weeks, seconds, days and so on, but none of it is clicking.

You have :
kNoWeeks = 49 (3 weeks vacation????)
You have kNoDays=163 (Days worked in a year????)
kNoSeconds=18424; (I have no clue)

Your TimeSchedule array has 164 rows of data. (you obviously don't like 0 based arrays)
Each row consists of 7 values with the first one never used.

What does this data represent and where did the values come from?

The entire TimeSchedule array is a key into the gaSeconds Array.
What is the relationship?

What exactly is the problem that you are trying to solve?
If I understand the question I can help you with the answer.

Bill Butler


Nov 17 '05 #9

P: n/a
Hi Bill,

Marcus has already solved my problem. He is pretty good let me tell you as
there are not many people that actually understand it in a vacuum, but he
did.
It is kind of esoteric, but he just understood what I wanted to do face
value and did a great job.

I will try to be a little bit more explicit next time.

Thanks anyways Bill

Roy
"Bill Butler" <qw****@asdf.com> wrote in message
news:QFv2f.1486$KR1.1352@trndny06...
Roy,

I have looked at your program and I cannot truly figure out what you are
doing.
I see names like weeks, seconds, days and so on, but none of it is
clicking.

You have :
kNoWeeks = 49 (3 weeks vacation????)
You have kNoDays=163 (Days worked in a year????)
kNoSeconds=18424; (I have no clue)

Your TimeSchedule array has 164 rows of data. (you obviously don't like 0
based arrays)
Each row consists of 7 values with the first one never used.

What does this data represent and where did the values come from?

The entire TimeSchedule array is a key into the gaSeconds Array.
What is the relationship?

What exactly is the problem that you are trying to solve?
If I understand the question I can help you with the answer.

Bill Butler

Nov 17 '05 #10

P: n/a

"Roy Gourgi" <ro***@videotron.ca> wrote in message
news:tO********************@weber.videotron.net...
Hi Bill,

Marcus has already solved my problem. He is pretty good let me tell you as there are not many
people that actually understand it in a vacuum, but he did.
It is kind of esoteric, but he just understood what I wanted to do face value and did a great job.

I will try to be a little bit more explicit next time.

Thanks anyways Bill

Roy


Hi Roy,

Markus may have helped improve the efficiency of your program, but that does nothing for it's
maintainability.

The reason I am asking you to describe the problem you are trying to solve in more detail is because
the logic in your program is VERY difficult to follow. I can't imagine that the problem cannot be
solved in a simpler fashion. (I could be wrong). Your program flow feels more like a FORTRAN or
COBOL program than a C# program.

I am semi fascinated by what you are trying to do and would still like to know more.

Jon has suggested applying more Object orientation to the problem.
This is not a bad idea, but even some simpler concepts can help.

-- Passing data as parameters to a function instead of making it Global
-- If you don't need to return a value from a function use a return type of void
-- Verify that you REALLY need 6 levels of nested looping to solve your problem (perhaps you do, but
I am not yet convinced)
-- Many more

So, while I am glad that Markus improved the behavior of the program,
I am not convinced that it is going about it in the most efficient way.

Often, at my job, I come across a massively complex program that I can't seem to wrap my brain
around.
After days of banging my head against the wall I get a revelation:
OOOHHHHH, That's what he was trying to do!!!!!!!!!
Often it could be done in a substantially clearer fashion.

So, if you give us a detailed description of the problem I think we can make this program
faster and much more maintainable

Bill


Nov 17 '05 #11

P: n/a
Bill,

Well believe it or not, you are right in the sense that it is a lot like
FORTRAN because that is the nature of the problem at hand. I am sure that
Markus will tell you himself that OOP in this case, it would be futile and
in fact would hinder the performance, I believe. I am not a seasoned
programmer by any means like you or Markus, but I do conceptualize things
quite well and come up with some pretty good ideas.

BTW Markus I tried to email you but I get an error. My program in C# was a
watered down version of my C++ program (which believe it or not is almost
identical to your final version but you did give me a couple of good ideas).
The main difference between our programs is that I did not used a jagged
array as I don't believe C++ supports them (I do not know C++ nor any
language for that matter very well). For your information, I used 3 x 1
dimensional arrays which make the program much simpler and intuitive. My
main reason was to see why my loops were executing so slow in C# and I think
that you answered that question when you said that the for looping in C# is
not that good, actually it stinks. I am not very knowledgeable when it comes
to programming, but I am a good problem solver.

My actual program in C++ is 30,000 lines and growing and I wanted to see if
it would be worth it to transport it to C# especially because I have to use
some very large databases. Do you think it would be?

I am very curious Markus, if you understand the nature of the problem
yourself and the context in which it is used as you came up with some
brilliant answers. Are you a mathematician, because there are not many
people that understand this problem as it is quite complex.

Roy


"Bill Butler" <qw****@asdf.com> wrote in message
news:2hw2f.3382$Iq3.1250@trndny01...

"Roy Gourgi" <ro***@videotron.ca> wrote in message
news:tO********************@weber.videotron.net...
Hi Bill,

Marcus has already solved my problem. He is pretty good let me tell you
as there are not many people that actually understand it in a vacuum, but
he did.
It is kind of esoteric, but he just understood what I wanted to do face
value and did a great job.

I will try to be a little bit more explicit next time.

Thanks anyways Bill

Roy


Hi Roy,

Markus may have helped improve the efficiency of your program, but that
does nothing for it's maintainability.

The reason I am asking you to describe the problem you are trying to solve
in more detail is because the logic in your program is VERY difficult to
follow. I can't imagine that the problem cannot be solved in a simpler
fashion. (I could be wrong). Your program flow feels more like a FORTRAN
or COBOL program than a C# program.

I am semi fascinated by what you are trying to do and would still like to
know more.

Jon has suggested applying more Object orientation to the problem.
This is not a bad idea, but even some simpler concepts can help.

-- Passing data as parameters to a function instead of making it Global
-- If you don't need to return a value from a function use a return type
of void
-- Verify that you REALLY need 6 levels of nested looping to solve your
problem (perhaps you do, but I am not yet convinced)
-- Many more

So, while I am glad that Markus improved the behavior of the program,
I am not convinced that it is going about it in the most efficient way.

Often, at my job, I come across a massively complex program that I can't
seem to wrap my brain around.
After days of banging my head against the wall I get a revelation:
OOOHHHHH, That's what he was trying to do!!!!!!!!!
Often it could be done in a substantially clearer fashion.

So, if you give us a detailed description of the problem I think we
can make this program faster and much more maintainable

Bill

Nov 17 '05 #12

P: n/a
Roy Gourgi <ro***@videotron.ca> wrote:
Well believe it or not, you are right in the sense that it is a lot like
FORTRAN because that is the nature of the problem at hand. I am sure that
Markus will tell you himself that OOP in this case, it would be futile and
in fact would hinder the performance, I believe.
I think that's making a bit of an assumption about Markus's
viewpoints...

As for it being futile and hindering performance - you can't know until
you've tried. One thing I know is that optimising code which is easily
understood is *much* easier than optimising code which is obscure.

<snip>
My main reason was to see why my loops were executing so slow in C#
and I think that you answered that question when you said that the
for looping in C# is not that good, actually it stinks.
I think you don't have nearly enough evidence on which to base that
viewpoint - especially as you've now said that Markus's C# version runs
faster than the C++ version!
I am not very knowledgeable when it comes to programming, but I am a
good problem solver.
I think the main thing you need to apply that to is how to make it
clear what the code is meant to do. Readability is very, very important
- if your code isn't readable, chances are it has bugs.
My actual program in C++ is 30,000 lines and growing and I wanted to see if
it would be worth it to transport it to C# especially because I have to use
some very large databases. Do you think it would be?


Using very large databases doesn't depend on using C#. However, if you
don't have readable code, you're likely to run into all kinds of
problems, whatever language you write the code in.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Nov 17 '05 #13

P: n/a
"Bill Butler" <qw****@asdf.com> wrote in message
news:QFv2f.1486$KR1.1352@trndny06...
Roy,

I have looked at your program and I cannot truly figure out what you are
doing.


That's one way to make sure you don't get fired - make finding a replacement
impossible ;o)
Nov 17 '05 #14

P: n/a
Roy Gourgi <ro***@videotron.ca> wrote:
I am new to C#. I have the same time scheduling program written in C++ and
it is 5 times faster than my version in C#.
Why is it so slow as I thought that C# was only a little slower than C++?
What am I doing wrong?


<snip>

Okay, I've had another look, and really tried hard to understand what's
going on. Here's what I've worked out so far:

You really only treat gaSumWorkDays as being true or false, right?
Using a bool array makes this clearer. Then each condition just changes
to:

if (GlobalValues.gaSumWorkDays[GlobalValues.gaSeconds[x,1]+
GlobalValues.gaSeconds[y,2]+
GlobalValues.gaSeconds[z,3]])

for some x, y and z, where 0 < x < y < z < 50. And you're counting all
the possibilities of x, y and z where that's not true - is that right?

Unfortunately, the way I see it, it must be more complicated than that
- because you're counting the case where (say) x=2, y=3, z=4 twice -
once when lp1=2, lp2=3, lp3=4, and once when lp2=2, lp3=3, lp4=4. Is
that deliberate? What does it signify, compared with the case of x=1,
y=2, z=3 which is only counted once?

It would really help if you'd explain what the code is meant to
actually do, because I strongly suspect there are much faster ways of
calculating the same answer - once we know what the question is.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Nov 17 '05 #15

P: n/a
Hi Bill,

Unfortunately I do not share that thought, that OOP is always the panacea to
all programming. I have dabbled in OOP with Visual FoxPro (the language that
I know best) even though I know that the OOP in VFP is not the classic OOP
paradigm like C#. Nonetheless, sometimes we tend to use something just
because it is available and not necessarily because it is the best
alternative. I certainly believe that OOP is clearly superior to procedure
driven programming, but by the same token I do think that it has to be used
properly. For example I think that when you use inheritance and override
many functions and create too many child classes, that it could become
unwieldly and complex.

To satisfy your curiosity, this is a combinatorial problem. I am a
combinatorist and a pretty good one at that I may say. I am not sure if
Markus knows anything about combinatorics or it's uses, though, by the way
that he solved that problem I would tend to believe he must have some
background in mathematics or logistics. Unbeknownst to him I think, is that
he just re-created the fastest timing checker ever made (actually he even
taught me a couple of things). :)

So you see in this case I cannot see how OOP can help as all the processing
has to be done in the same function.

I hope that I can make the transition to C# as I have to create databases
that are incredibly huge (numbers that are surreal). The reason why I want
to move to C# is that I think that C# and VS.Net are where everything is
headed and it seems to be more intuitive than C++ and there will probably be
a lot of support.

Hope this helps

Roy

"Bill Butler" <qw****@asdf.com> wrote in message
news:2hw2f.3382$Iq3.1250@trndny01...

"Roy Gourgi" <ro***@videotron.ca> wrote in message
news:tO********************@weber.videotron.net...
Hi Bill,

Marcus has already solved my problem. He is pretty good let me tell you
as there are not many people that actually understand it in a vacuum, but
he did.
It is kind of esoteric, but he just understood what I wanted to do face
value and did a great job.

I will try to be a little bit more explicit next time.

Thanks anyways Bill

Roy


Hi Roy,

Markus may have helped improve the efficiency of your program, but that
does nothing for it's maintainability.

The reason I am asking you to describe the problem you are trying to solve
in more detail is because the logic in your program is VERY difficult to
follow. I can't imagine that the problem cannot be solved in a simpler
fashion. (I could be wrong). Your program flow feels more like a FORTRAN
or COBOL program than a C# program.

I am semi fascinated by what you are trying to do and would still like to
know more.

Jon has suggested applying more Object orientation to the problem.
This is not a bad idea, but even some simpler concepts can help.

-- Passing data as parameters to a function instead of making it Global
-- If you don't need to return a value from a function use a return type
of void
-- Verify that you REALLY need 6 levels of nested looping to solve your
problem (perhaps you do, but I am not yet convinced)
-- Many more

So, while I am glad that Markus improved the behavior of the program,
I am not convinced that it is going about it in the most efficient way.

Often, at my job, I come across a massively complex program that I can't
seem to wrap my brain around.
After days of banging my head against the wall I get a revelation:
OOOHHHHH, That's what he was trying to do!!!!!!!!!
Often it could be done in a substantially clearer fashion.

So, if you give us a detailed description of the problem I think we
can make this program faster and much more maintainable

Bill

Nov 17 '05 #16

P: n/a
Hi Jon,

If you read my previous email it will shed some light on the matter at hand.

Yes, that is right gaSumWorkDays is just treated to check if it is true or
false, but as I mentioned earlier this is a watered down version of my
program and you do not see why those values are true or false. Yes indeed it
is more complicated than that, but everything is done methodically in an
orderly fashion and although it seems that there is some redundancy, it is
unavoidable.

This is a combinatorial timing problem and believe it or not, this is the
fastest algorithm in the world. If you look at the order in which the loops
are actually tested to see if they are true or false, you might understand
it. They are purposely done in that order to maximize speed by avoiding as
much redundancy as possible, even though it might not seem intuitive.

Hope this helps

Roy


"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP***********************@msnews.microsoft.co m...
Roy Gourgi <ro***@videotron.ca> wrote:
I am new to C#. I have the same time scheduling program written in C++
and
it is 5 times faster than my version in C#.
Why is it so slow as I thought that C# was only a little slower than C++?
What am I doing wrong?


<snip>

Okay, I've had another look, and really tried hard to understand what's
going on. Here's what I've worked out so far:

You really only treat gaSumWorkDays as being true or false, right?
Using a bool array makes this clearer. Then each condition just changes
to:

if (GlobalValues.gaSumWorkDays[GlobalValues.gaSeconds[x,1]+
GlobalValues.gaSeconds[y,2]+
GlobalValues.gaSeconds[z,3]])

for some x, y and z, where 0 < x < y < z < 50. And you're counting all
the possibilities of x, y and z where that's not true - is that right?

Unfortunately, the way I see it, it must be more complicated than that
- because you're counting the case where (say) x=2, y=3, z=4 twice -
once when lp1=2, lp2=3, lp3=4, and once when lp2=2, lp3=3, lp4=4. Is
that deliberate? What does it signify, compared with the case of x=1,
y=2, z=3 which is only counted once?

It would really help if you'd explain what the code is meant to
actually do, because I strongly suspect there are much faster ways of
calculating the same answer - once we know what the question is.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too

Nov 17 '05 #17

P: n/a
Roy Gourgi <ro***@videotron.ca> wrote:
If you read my previous email it will shed some light on the matter at hand.
I thought I'd read all the articles you'd posted, but I haven't seen
any explanation for what it's actually trying to do.
Yes, that is right gaSumWorkDays is just treated to check if it is true or
false, but as I mentioned earlier this is a watered down version of my
program and you do not see why those values are true or false. Yes indeed it
is more complicated than that, but everything is done methodically in an
orderly fashion and although it seems that there is some redundancy, it is
unavoidable.
Unavoidable redundancy usually sounds like it's just not be solved
*yet* to me :)
This is a combinatorial timing problem and believe it or not, this is the
fastest algorithm in the world. If you look at the order in which the loops
are actually tested to see if they are true or false, you might understand
it. They are purposely done in that order to maximize speed by avoiding as
much redundancy as possible, even though it might not seem intuitive.


You haven't answered my question as to whether you are actually
intending to count some combinations (eg 2,3,4) multiple times. Even if
you are, I would have thought it would be easier to only try each
combination once (i.e. using a triple loop rather than six) and then if
you hit a "missing" time, work out how many times you would have hit it
if you'd used your original algorithm.

You've praised Markus's understanding of the problem several times, but
as he said, the fastest gain was just from using jagged arrays rather
than rectangular arrays. As far as I've seen, you've still not said why
you couldn't use rectangular arrays to start with.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Nov 17 '05 #18

P: n/a
Roy Gourgi <ro***@videotron.ca> wrote:
If you read my previous email it will shed some light on the matter at hand.
I thought I'd read all the articles you'd posted, but I haven't seen
any explanation for what it's actually trying to do.
Yes, that is right gaSumWorkDays is just treated to check if it is true or
false, but as I mentioned earlier this is a watered down version of my
program and you do not see why those values are true or false. Yes indeed it
is more complicated than that, but everything is done methodically in an
orderly fashion and although it seems that there is some redundancy, it is
unavoidable.
Unavoidable redundancy usually sounds like it's just not be solved
*yet* to me :)
This is a combinatorial timing problem and believe it or not, this is the
fastest algorithm in the world. If you look at the order in which the loops
are actually tested to see if they are true or false, you might understand
it. They are purposely done in that order to maximize speed by avoiding as
much redundancy as possible, even though it might not seem intuitive.


You haven't answered my question as to whether you are actually
intending to count some combinations (eg 2,3,4) multiple times. Even if
you are, I would have thought it would be easier to only try each
combination once (i.e. using a triple loop rather than six) and then if
you hit a "missing" time, work out how many times you would have hit it
if you'd used your original algorithm.

You've praised Markus's understanding of the problem several times, but
as he said, the fastest gain was just from using jagged arrays rather
than rectangular arrays. As far as I've seen, you've still not said why
you couldn't use jagged arrays to start with.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Nov 17 '05 #19

P: n/a
Jon Skeet [C# MVP] <sk***@pobox.com> wrote:

<snip>

Ignore the post this is a reply to - I tried to cancel it before it was
posted, but apparently I just missed... the last paragraph had
"rectangular" where I meant "jagged", hence the repost.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Nov 17 '05 #20

P: n/a
FWIW, I did, it didn't.
"Roy Gourgi" <ro***@videotron.ca> wrote in message
news:vT*******************@wagner.videotron.net...
Hi Jon,

If you read my previous email it will shed some light on the matter at

hand.
Nov 17 '05 #21

P: n/a
Jon,
Unavoidable redundancy usually sounds like it's just not be solved
*yet* to me :)
Believe it or not, in most combinatorial problems there is some *unavoidable
redundancy* as most combinatorial covering designs are not perfect (i.e.
they contain some unavoidable redundancy). There are instances of perfect
combinatorial designs such as this design C(22,6,3)=77 and when they are
perfect they are call t-designs. But most designs do not fall under this
perfect category and they are thus much harder to find than their
counterparts.

If you are interested I can shed some more light, but it gets more complex.
:)

You haven't answered my question as to whether you are actually
intending to count some combinations (eg 2,3,4) multiple times. Even if
you are, I would have thought it would be easier to only try each
combination once (i.e. using a triple loop rather than six) and then if
you hit a "missing" time, work out how many times you would have hit it
if you'd used your original algorithm.
No, I am not counting the instances of a particular combination such as
2,3,4 because if you look at the code carefully, any combination is never
checked more than once in any of the 6 columns in the gaSeconds. That is why
as I mentioned in my other posts, the way the search is conducted is of the
essence. If 3 points such as 2,3,4 appear in any one of 6 numbers, it would
be better if they appear in the first 3 of the 6 because that would speed up
the search. Do you follow?
You've praised Markus's understanding of the problem several times, but
as he said, the fastest gain was just from using jagged arrays rather
than rectangular arrays. As far as I've seen, you've still not said why
you couldn't use rectangular arrays to start with.
First of all, I don't think that C++ supports jagged arrays (correct me if I
am wrong). Furthermore, as I reiterated a few times, my knowledge in
programming is not as extensive as yours and I thought jagged arrays are to
be used only when the arrays are not rectangular and in my case they always
are. I was not aware that jagged arrays would speed up the search process
(one of the new things that I learnt). In my original program I use 3 one
dimensional arrays (i.e. gaSeconds1,gaSeconds2,gaSeconds3) which I guess is
analogous to a jagged array. I think it may even be faster than a jagged
array as you are only accessing a one dimension array at a time (correct me
if I am wrong) but I was too lazy to try to see which one is faster. Also,
to me it seems more natural and intuitive to have several one dimensional
arrays, but this might just be a matter of preference. BTW do you know which
would be faster a jagged array, or multiple one dimensional arrays?

Hope this helps

Roy

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om... Roy Gourgi <ro***@videotron.ca> wrote:
If you read my previous email it will shed some light on the matter at
hand.


I thought I'd read all the articles you'd posted, but I haven't seen
any explanation for what it's actually trying to do.
Yes, that is right gaSumWorkDays is just treated to check if it is true
or
false, but as I mentioned earlier this is a watered down version of my
program and you do not see why those values are true or false. Yes indeed
it
is more complicated than that, but everything is done methodically in an
orderly fashion and although it seems that there is some redundancy, it
is
unavoidable.


Unavoidable redundancy usually sounds like it's just not be solved
*yet* to me :)
This is a combinatorial timing problem and believe it or not, this is the
fastest algorithm in the world. If you look at the order in which the
loops
are actually tested to see if they are true or false, you might
understand
it. They are purposely done in that order to maximize speed by avoiding
as
much redundancy as possible, even though it might not seem intuitive.


You haven't answered my question as to whether you are actually
intending to count some combinations (eg 2,3,4) multiple times. Even if
you are, I would have thought it would be easier to only try each
combination once (i.e. using a triple loop rather than six) and then if
you hit a "missing" time, work out how many times you would have hit it
if you'd used your original algorithm.

You've praised Markus's understanding of the problem several times, but
as he said, the fastest gain was just from using jagged arrays rather
than rectangular arrays. As far as I've seen, you've still not said why
you couldn't use rectangular arrays to start with.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too

Nov 17 '05 #22

P: n/a
Roy Gourgi <ro***@videotron.ca> wrote:
Unavoidable redundancy usually sounds like it's just not be solved
*yet* to me :)
Believe it or not, in most combinatorial problems there is some *unavoidable
redundancy* as most combinatorial covering designs are not perfect (i.e.
they contain some unavoidable redundancy). There are instances of perfect
combinatorial designs such as this design C(22,6,3)=77 and when they are
perfect they are call t-designs. But most designs do not fall under this
perfect category and they are thus much harder to find than their
counterparts.

If you are interested I can shed some more light, but it gets more complex.
:)


Let's see how much progress we make elsewhere first... I can't remember
much of the combinatorics I did from university, unfortunately. (I
can't even remember how much we did.)
You haven't answered my question as to whether you are actually
intending to count some combinations (eg 2,3,4) multiple times. Even if
you are, I would have thought it would be easier to only try each
combination once (i.e. using a triple loop rather than six) and then if
you hit a "missing" time, work out how many times you would have hit it
if you'd used your original algorithm.


No, I am not counting the instances of a particular combination such as
2,3,4 because if you look at the code carefully, any combination is never
checked more than once in any of the 6 columns in the gaSeconds. That is why
as I mentioned in my other posts, the way the search is conducted is of the
essence. If 3 points such as 2,3,4 appear in any one of 6 numbers, it would
be better if they appear in the first 3 of the 6 because that would speed up
the search. Do you follow?


That may well be the intention, but it's not what actually happens, as
far as I can tell. If you make the program dump out any times when it's
checking {2,3,4} just with the lp1/lp2/lp3, lp2/lp3/lp4 combinations,
you'll see it does it several times.

However, it looks like the code doesn't actually do what I thought it
did - a brute force search for all x/y/z such that 0 < x < y < z < 50
and gaSumWorkDays[gaSeconds[x,1]+gaSeconds[y,2]+gaSeconds[z,3]]<=0
finds plenty.

So, one more time: what is this actually trying to do? Without
understanding the code in depth (which is tricky, due to the way it's
written) it's very hard to do anything other the kind of refactoring
which Markus performed.
You've praised Markus's understanding of the problem several times, but
as he said, the fastest gain was just from using jagged arrays rather
than rectangular arrays. As far as I've seen, you've still not said why
you couldn't use rectangular arrays to start with.


First of all, I don't think that C++ supports jagged arrays (correct me if I
am wrong).


I wouldn't like to say for sure, to be honest. I'm not sure what you
*do* get in C++ - it's been a while. I *suspect* that C++ doesn't
actually support *rectangular* arrays directly - you have to create a
one-dimensional array with a size of the product of the individual rank
lengths.
Furthermore, as I reiterated a few times, my knowledge in
programming is not as extensive as yours and I thought jagged arrays are to
be used only when the arrays are not rectangular and in my case they always
are.
No - rectangular arrays are definitely more memory efficient, but
slower in .NET.
I was not aware that jagged arrays would speed up the search process
(one of the new things that I learnt).
But when I told you that originally, you said that you *couldn't* use
jagged arrays. Is that actually the case (and in which case, why?) or
not?
In my original program I use 3 one
dimensional arrays (i.e. gaSeconds1,gaSeconds2,gaSeconds3) which I guess is
analogous to a jagged array.
Yes, pretty much.
I think it may even be faster than a jagged
array as you are only accessing a one dimension array at a time (correct me
if I am wrong) but I was too lazy to try to see which one is faster. Also,
to me it seems more natural and intuitive to have several one dimensional
arrays, but this might just be a matter of preference. BTW do you know which
would be faster a jagged array, or multiple one dimensional arrays?


I don't know which would be faster, to be honest - you'd need to
benchmark it. Of course, doing that is *much* easier if you refactor
the test bit into a separate method, which is almost certain to be
inlined anyway. Just an example of why it's important to code in a
maintainable way rather than assuming that anything which is
understandable won't perform.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Nov 17 '05 #23

P: n/a
> That may well be the intention, but it's not what actually happens, as
far as I can tell. If you make the program dump out any times when it's
checking {2,3,4} just with the lp1/lp2/lp3, lp2/lp3/lp4 combinations,
you'll see it does it several times.
Yes but not in any particular row. For example if you have the 6 numbers
2,3,4,5,6,7 then it only checks the 2,3,4 one time. I told you this is a
watered down version of my program.
So, one more time: what is this actually trying to do? Without
understanding the code in depth (which is tricky, due to the way it's
written) it's very hard to do anything other the kind of refactoring
which Markus performed.
It is tryiing to see if all the any one of the 3 number point are contained
in all the possible combinations ranging from 1 to 49.

Hope this helps
Roy

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om... Roy Gourgi <ro***@videotron.ca> wrote:
> Unavoidable redundancy usually sounds like it's just not be solved
> *yet* to me :)


Believe it or not, in most combinatorial problems there is some
*unavoidable
redundancy* as most combinatorial covering designs are not perfect (i.e.
they contain some unavoidable redundancy). There are instances of perfect
combinatorial designs such as this design C(22,6,3)=77 and when they are
perfect they are call t-designs. But most designs do not fall under this
perfect category and they are thus much harder to find than their
counterparts.

If you are interested I can shed some more light, but it gets more
complex.
:)


Let's see how much progress we make elsewhere first... I can't remember
much of the combinatorics I did from university, unfortunately. (I
can't even remember how much we did.)
> You haven't answered my question as to whether you are actually
> intending to count some combinations (eg 2,3,4) multiple times. Even if
> you are, I would have thought it would be easier to only try each
> combination once (i.e. using a triple loop rather than six) and then if
> you hit a "missing" time, work out how many times you would have hit it
> if you'd used your original algorithm.


No, I am not counting the instances of a particular combination such as
2,3,4 because if you look at the code carefully, any combination is never
checked more than once in any of the 6 columns in the gaSeconds. That is
why
as I mentioned in my other posts, the way the search is conducted is of
the
essence. If 3 points such as 2,3,4 appear in any one of 6 numbers, it
would
be better if they appear in the first 3 of the 6 because that would speed
up
the search. Do you follow?


That may well be the intention, but it's not what actually happens, as
far as I can tell. If you make the program dump out any times when it's
checking {2,3,4} just with the lp1/lp2/lp3, lp2/lp3/lp4 combinations,
you'll see it does it several times.

However, it looks like the code doesn't actually do what I thought it
did - a brute force search for all x/y/z such that 0 < x < y < z < 50
and gaSumWorkDays[gaSeconds[x,1]+gaSeconds[y,2]+gaSeconds[z,3]]<=0
finds plenty.

So, one more time: what is this actually trying to do? Without
understanding the code in depth (which is tricky, due to the way it's
written) it's very hard to do anything other the kind of refactoring
which Markus performed.
> You've praised Markus's understanding of the problem several times, but
> as he said, the fastest gain was just from using jagged arrays rather
> than rectangular arrays. As far as I've seen, you've still not said why
> you couldn't use rectangular arrays to start with.


First of all, I don't think that C++ supports jagged arrays (correct me
if I
am wrong).


I wouldn't like to say for sure, to be honest. I'm not sure what you
*do* get in C++ - it's been a while. I *suspect* that C++ doesn't
actually support *rectangular* arrays directly - you have to create a
one-dimensional array with a size of the product of the individual rank
lengths.
Furthermore, as I reiterated a few times, my knowledge in
programming is not as extensive as yours and I thought jagged arrays are
to
be used only when the arrays are not rectangular and in my case they
always
are.


No - rectangular arrays are definitely more memory efficient, but
slower in .NET.
I was not aware that jagged arrays would speed up the search process
(one of the new things that I learnt).


But when I told you that originally, you said that you *couldn't* use
jagged arrays. Is that actually the case (and in which case, why?) or
not?
In my original program I use 3 one
dimensional arrays (i.e. gaSeconds1,gaSeconds2,gaSeconds3) which I guess
is
analogous to a jagged array.


Yes, pretty much.
I think it may even be faster than a jagged
array as you are only accessing a one dimension array at a time (correct
me
if I am wrong) but I was too lazy to try to see which one is faster.
Also,
to me it seems more natural and intuitive to have several one dimensional
arrays, but this might just be a matter of preference. BTW do you know
which
would be faster a jagged array, or multiple one dimensional arrays?


I don't know which would be faster, to be honest - you'd need to
benchmark it. Of course, doing that is *much* easier if you refactor
the test bit into a separate method, which is almost certain to be
inlined anyway. Just an example of why it's important to code in a
maintainable way rather than assuming that anything which is
understandable won't perform.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too

Nov 17 '05 #24

P: n/a
Roy Gourgi <ro***@videotron.ca> wrote:
That may well be the intention, but it's not what actually happens, as
far as I can tell. If you make the program dump out any times when it's
checking {2,3,4} just with the lp1/lp2/lp3, lp2/lp3/lp4 combinations,
you'll see it does it several times.


Yes but not in any particular row. For example if you have the 6 numbers
2,3,4,5,6,7 then it only checks the 2,3,4 one time. I told you this is a
watered down version of my program.


Yes, which is part of the problem - you've never actually told us what
it's meant to do.
So, one more time: what is this actually trying to do? Without
understanding the code in depth (which is tricky, due to the way it's
written) it's very hard to do anything other the kind of refactoring
which Markus performed.


It is tryiing to see if all the any one of the 3 number point are contained
in all the possible combinations ranging from 1 to 49.


Please try explaining that in more straightforward terms. As far as I
can tell, it attempts to find whether it can find any *6* numbers where
the condition (the sum etc) is true for *all* combinations of 3 numbers
within those 6.

If you only look for 3 at a time, there are plenty of examples for
which the condition holds - but there are no 6 numbers where it holds
for all combinations of three of those numbers.

I can't help but feel there must be a more efficient way of looking -
for instance, if you find that the condition doesn't hold for
(30,31,32) when those are the later three numbers, then there's no
point in looking through them at all for *any* earlier set of numbers -
the sort of optimisation you've got for skipping past early
combinations. I'll have to have a think about how to use that - but I
can only do so if you can confirm that the program is trying to do what
I think it is.

In the meantime, I'll attempt to convert it into a more readable form
which lends itself to optimisation.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Nov 17 '05 #25

P: n/a

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
<snip>
So, one more time: what is this actually trying to do? Without
understanding the code in depth (which is tricky, due to the way it's
written) it's very hard to do anything other the kind of refactoring
which Markus performed.

<snip>

OK,
I got tired of trying to extract deeply held secrets from Roy, so I did some digging.
It turns out that Roy loves the lottery (or at least the a mathematics surrounding it)

The 163 rows of data in the TimeSchedule Array were 163 lottery tickets.
This particular lottery has 49 numbers and you choose 6 of them.

The idea of the game is to find the minimum number of lottery tickets that you would need to buy in
order to ensure that you were guaranteed to always match a minimum of 3 numbers on at least 1
ticket. Of course the same logic could be applied for 4 or 5 number matches, or other lotteries, or
other variations.

So the short description of his watered down program would be as follows.
Given a set of N lottery tickets (163) in this case, with certain numbers on each ticket
(TimeSchedule Array)
Verify that we have a covering() - for any valid lottery number(the 6 loops) verify that at
least 1 of our tickets matches 3 of the numbers.

That's it!!
No state secrets!!
No concept to vast for our tiny minds!!!

Now most likely his REAL program has algorithms for attempting to generate minimal coverings for
certain problems.
He then needs to verify that his solution is a covering (minimal is much tougher)

Apparently Roy wanted us off the scent given the names he chose for is variables.
TimeSchedule ---> LotteryTickets
kNoWeeks=49; ---> How many numbers in the lottery
kNoDays=163; ---> How many tickets
kNoSeconds=18424; ---> 49 choose 3 = (49*48*47)/(3*2*1)
gaWorkDays= new int [7]; ---> Numbers on a given ticket

I would be curious to hear from Roy if there is ANY connection to the variable names.

For more info look here:
http://pages.infinit.net/royng/index.htm

or Google for - combinatorial covering designs

Bill


Nov 17 '05 #26

P: n/a
Very good, you hit the nail right on the button. Impressive. :) Now was that
not FUN!!!
Well believe it or not, combinatorics is used in many applications, even for
debugging software. So yes indirectly there could be a connection. Covering
designs are templates and they could be used in any application.

Roy

"Bill Butler" <qw****@asdf.com> wrote in message
news:6ET2f.14202$Tn5.5262@trnddc08...

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
<snip>
So, one more time: what is this actually trying to do? Without
understanding the code in depth (which is tricky, due to the way it's
written) it's very hard to do anything other the kind of refactoring
which Markus performed.

<snip>

OK,
I got tired of trying to extract deeply held secrets from Roy, so I did
some digging.
It turns out that Roy loves the lottery (or at least the a mathematics
surrounding it)

The 163 rows of data in the TimeSchedule Array were 163 lottery tickets.
This particular lottery has 49 numbers and you choose 6 of them.

The idea of the game is to find the minimum number of lottery tickets that
you would need to buy in order to ensure that you were guaranteed to
always match a minimum of 3 numbers on at least 1 ticket. Of course the
same logic could be applied for 4 or 5 number matches, or other lotteries,
or other variations.

So the short description of his watered down program would be as follows.
Given a set of N lottery tickets (163) in this case, with certain
numbers on each ticket (TimeSchedule Array)
Verify that we have a covering() - for any valid lottery number(the 6
loops) verify that at least 1 of our tickets matches 3 of the numbers.

That's it!!
No state secrets!!
No concept to vast for our tiny minds!!!

Now most likely his REAL program has algorithms for attempting to generate
minimal coverings for certain problems.
He then needs to verify that his solution is a covering (minimal is much
tougher)

Apparently Roy wanted us off the scent given the names he chose for is
variables.
TimeSchedule ---> LotteryTickets
kNoWeeks=49; ---> How many numbers in the lottery
kNoDays=163; ---> How many tickets
kNoSeconds=18424; ---> 49 choose 3 = (49*48*47)/(3*2*1)
gaWorkDays= new int [7]; ---> Numbers on a given ticket

I would be curious to hear from Roy if there is ANY connection to the
variable names.

For more info look here:
http://pages.infinit.net/royng/index.htm

or Google for - combinatorial covering designs

Bill



Nov 17 '05 #27

P: n/a
Bill Butler <qw****@asdf.com> wrote:

<snip>
Apparently Roy wanted us off the scent given the names he chose for is variables.
TimeSchedule ---> LotteryTickets
kNoWeeks=49; ---> How many numbers in the lottery
kNoDays=163; ---> How many tickets
kNoSeconds=18424; ---> 49 choose 3 = (49*48*47)/(3*2*1)
gaWorkDays= new int [7]; ---> Numbers on a given ticket

I would be curious to hear from Roy if there is ANY connection to the variable names.


Thanks for doing the research, Bill. I suspect this will be my last
post to this thread, as I'm not much of a fan of helping people who
effectively lie about what their code is for in the first place.

If Roy had been honest in the first place, I'd have been much more
interested in helping...

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Nov 17 '05 #28

P: n/a
Hi,

I did not lie. All I asked for was for some help which I did receive from
Markus. He did not ask any questions and he solved my problem. What is the
big deal?

Thanks anyways

Roy

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Bill Butler <qw****@asdf.com> wrote:

<snip>
Apparently Roy wanted us off the scent given the names he chose for is
variables.
TimeSchedule ---> LotteryTickets
kNoWeeks=49; ---> How many numbers in the
lottery
kNoDays=163; ---> How many tickets
kNoSeconds=18424; ---> 49 choose 3 = (49*48*47)/(3*2*1)
gaWorkDays= new int [7]; ---> Numbers on a given ticket

I would be curious to hear from Roy if there is ANY connection to the
variable names.


Thanks for doing the research, Bill. I suspect this will be my last
post to this thread, as I'm not much of a fan of helping people who
effectively lie about what their code is for in the first place.

If Roy had been honest in the first place, I'd have been much more
interested in helping...

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too

Nov 17 '05 #29

P: n/a
Roy Gourgi <ro***@videotron.ca> wrote:
I did not lie. All I asked for was for some help which I did receive from
Markus. He did not ask any questions and he solved my problem. What is the
big deal?


"I have the same time scheduling program written in C++ and
it is 5 times faster than my version in C#."

This is now clearly *not* a time scheduling program, but you changed
your variable names etc to pretend it was.

You've been secretive and dishonest. I suspect I'm not the only one who
dislikes being treated this way.

(By the way, others helped you as well - you just chose to ignore their
help, like my very first post which suggested using jagged arrays...)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Nov 17 '05 #30

This discussion thread is closed

Replies have been disabled for this discussion.