Performance differences between linq and classical method - c#

I want to know performance differences between below two code lines. Which one is faster?
1.
anyList = Enumerable.Range(0, 1440).Select((n, i) =>
{
if ((i >= 480 && i < 790) || (i >= 1050 && i < 1170)
return 0;
else if ((i >= 790 && i < 1050)
return 1;
else
return 2;
}).ToList();
2.
for (int i = 0; i < 1440; i++)
{
if ((i >= 480 && i < 790) || (i >= 1050 && i < 1170)
anyLisy.Add(0);
else if ((i >= 790 && i < 1050)
anyLisy.Add(1);
else
anyLisy.Add(2);
}
Which one is faster, which one has much more allocated memory?

use StopWatch and make some benchmark something like this
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
for (int i = 0; i < 1440; i++)
{
if ((i >= 480 && i < 790) || (i >= 1050 && i < 1170))
anyLisy.Add(0);
else if (i >= 790 && i < 1050)
anyLisy.Add(1);
else
anyLisy.Add(2);
}
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
// Format and display the TimeSpan value.
string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
ts.Hours, ts.Minutes, ts.Seconds,
ts.Milliseconds / 10);
Console.WriteLine("RunTime " + elapsedTime);

Related

(C#) How can I make all these "else if" statements more condensed and how can I optimize my code better?

Okay, I have a load of else if statements, is there a way to condense them into fewer lines of code? Like make one if statement for all of it? And what ways could I make my code more optimize and easier to read?
int x;
int y;
int time=0;
Random rng = new Random();
int hrand_num = rng.Next(-24000, 24000);
int vrand_num = rng.Next(-24000, 24000);
x = hrand_num;
y = vrand_num;
while (true)
{
ConsoleKey key = Console.ReadKey().Key;
if (key == ConsoleKey.UpArrow)
{
y=y+2000;
}
else if (key == ConsoleKey.DownArrow)
{
y=y-2000;
}
else if (key == ConsoleKey.LeftArrow)
{
x = x-1000;
}
else if (key == ConsoleKey.RightArrow)
{
x = x+1000;
}
// Circumnavigate Players Position.
// North and South
if (y >= 24001)
{
y = -24000;
}
else if (y <= -24001)
{
y = 24000;
}
//West and East
else if (x >= 24001)
{
x = -24000;
}
else if (x <= -24001)
{
x = 24000;
}
// Setting Time Zones
if (x >= -2000 && x <= 0 )
{
time = 0;
}
else if (x >=
1 && x <= 2000)
{
time = 1;
}
else if (x >= 2001 && x <=4000)
{
time = 2;
}
else if (x >= 4001 && x <= 6000)
{
time = 3;
}
else if (x >= 6001 && x <= 8000)
{
time = 4;
}
else if (x >= 8001 && x <= 10000)
{
time = 5;
}
else if (x >= 10001 && x <= 12000)
{
time = 6;
}
else if (x >= 12001 && x <= 14000)
{
time = 7;
}
else if (x >= 14001 && x <= 16000)
{
time = 8;
}
else if (x >= 16001 && x <= 18000)
{
time = 9;
}
else if (x >= 18001 && x <= 20000)
{
time = 10;
}
else if (x >= 20001 && x <= 22000)
{
time = 11;
}
else if (x >= 22001 && x <= 24000)
{
time = 12;
}
else if (x == -24000 && x <= -22001)
{
time = 13;
}
else if (x >= -22000 && x <= -20001 )
{
time = 14;
}
else if (x >= -20000 && x <= -18001)
{
time = 15;
}
else if (x >= -18000 && x <= -16001)
{
time = 16;
}
else if (x >= -16000 && x <= -14001)
{
time = 17;
}
else if (x >= -14000 && x <= -12001)
{
time = 18;
}
else if (x >= -12000 && x <= -10001)
{
time = 19;
}
else if (x >= -10000 && x <= -8001)
{
time = 20;
}
else if (x >= -8000 && x <= -6001)
{
time = 21;
}
else if (x >= -6000 && x <= -4001)
{
time = 22;
}
else if (x >= -4000 && x <= -2001)
{
time = 23;
}
Console.WriteLine($"X: {x,6} Y: {y,6} Time: {time,3}");
}
```
Assuming that you are using C# 8.0 you may have a look at the switch statement and switch expressions: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/switch-expression (additionaly the patterns documentation is also helpful: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/patterns)
So you could write something like:
switch (key)
{
case ConsoleKey.UpArrow:
y=y+2000;
break;
// [...]
}
time = x switch
{
>= -2000 and <= 0 => 0,
>= 1 and <= 2000 => 1
// [...]
};
I would suggest that you take advantage of:
a switch statement for interpreting the arrow key
comparing the switch statement to an if loop, you can think of the first case as being the if condition and the remaning cases as being the else if conditions
Math.Abs( ) and Math.Sign( ) for circumnavigating the player's position
Math.Abs( ) returns the absolute value of the variable; e.g. will Math.Abs(x) return 5 both for x = 5 and x = -5
Math.Sign( ) returns the sign of the value; if the value is a negative number, it returns -1; if it's a positive number, it returns 1; if it's neither (0), it returns 0. This helps us determine the wanted sign of the updated value.
a switch expression for setting the time
seeing as the time value alone is determined by x in the end, you can use a switch expression rather than a switch statement to determine its value. The switch expression says that you want to determine the value of time based on the value of x; and each following condition is compared to x (<= -22001 is computed as x <= -22001). If the condition evaluates to true, the provided value is set as the value of time (=> 13 then sets time = 13).
It could be implemented like this:
int x;
int y;
Random rng = new Random();
int hrand_num = rng.Next(-24000, 24000);
int vrand_num = rng.Next(-24000, 24000);
x = hrand_num;
y = vrand_num;
while (true)
{
switch (Console.ReadKey().Key)
{
case ConsoleKey.UpArrow:
y += 2000;
break;
case ConsoleKey.DownArrow:
y -= 2000;
break;
case ConsoleKey.LeftArrow:
x -= 1000;
break;
case ConsoleKey.RightArrow:
x += 1000;
break;
}
// Circumnavigate Players Position.
// North and South
if (Math.Abs(y) > 24000)
{
y = -(Math.Sign(y) * 24000);
}
//West and East
else if (Math.Abs(x) > 24000)
{
x = -(Math.Sign(x) * 24000);
}
// Setting Time Zones
var time = x switch
{
<= -22001 => 13,
<= -20001 => 14,
<= -18001 => 15,
<= -16001 => 16,
<= -14001 => 17,
<= -12001 => 18,
<= -10001 => 19,
<= -8001 => 20,
<= -6001 => 21,
<= -4001 => 22,
<= -2001 => 23,
<= 0 => 0,
<= 2000 => 1,
<= 4000 => 2,
<= 6000 => 3,
<= 8000 => 4,
<= 10000 => 5,
<= 12000 => 6,
<= 14000 => 7,
<= 16000 => 8,
<= 18000 => 9,
<= 20000 => 10,
<= 22000 => 11,
<= 24000 => 12,
_ => 0
};
Console.WriteLine($"X: {x,6} Y: {y,6} Time: {time,3}");
I would also suggest introducing some constants; particularily for the value 24000.
You can use the following to cover all time cases
var time = x <= 24000
? x / 2000 + 1;
: (24000 - x) / 2000 + 13;

Comparing datatable value to integer in IF statement

I am working on a if statement that compare cell values to an integer. The method I used is convert.ToInt16. As result showing below, the if statement becomes very long. I am wondering if there an another approach to shorten the code?
int i, emplyNum;
for (int j = 1; j< 3; j++)
{
if ((( Convert.ToInt16(Employee.Rows[j][1]) - 1) < i && i < ( Convert.ToInt16(Employee.Rows[j][2]) + 1)) || ((Convert.ToInt16(Employee.Rows[j][3]) - 1) < i && i < (Convert.ToInt16(Employee.Rows[j][4]) + 1)) || ((Convert.ToInt16(Employee.Rows[j][5]) - 1) < i && i < (Convert.ToInt16(Employee.Rows[j][6]) + 1)))
{
emplyNum = j;
}
}

How to get 0 from subtracting two double numbers?

For some reason im getting a 2.7234235252E -17 instead of 0 when my program is subtracting .1 - .1, why is that? and how can i properly subtract? and as a third question, if i do subtract .1 - .1, does bool consider it 0? for example: 0 == .1 - .1 = true or false?
List<string> hd1List = new List<string>();
double hd1CD = 0;
double hd2CD = 0;
double hd3CD = 0;
double hd4CD = 0;
// for (int i = 0; i < 10; i++)
// {
if (hd1CD <= 0)
{
hd1List.Add("q");
hd1CD = 4;
hd1CD = hd1CD - .7;
}
Console.WriteLine(hd1CD);
Console.WriteLine(hd2CD);
Console.WriteLine(hd3CD);
Console.WriteLine(hd4CD);
if (hd2CD <= 0 && hd1CD >= .7)
{
hd1List.Add("e");
hd2CD = 1;
hd1CD = hd1CD - .7;
hd2CD = hd2CD - .7;
}
Console.WriteLine(hd1CD);
Console.WriteLine(hd2CD);
Console.WriteLine(hd3CD);
Console.WriteLine(hd4CD);
if (hd3CD <= 0 && hd1CD >= .2 && hd2CD >= .2)
{
hd1List.Add("r");
hd3CD = 5;
hd1CD = hd1CD - .2;
hd2CD = hd2CD - .2;
hd3CD = hd3CD - .2;
}
Console.WriteLine(hd1CD);
Console.WriteLine(hd2CD);
Console.WriteLine(hd3CD);
Console.WriteLine(hd4CD);
if (hd4CD <= 0 && hd1CD >= .1 && hd2CD >= .1 && hd3CD >= .1)
{
hd1List.Add("w");
hd4CD = 3;
hd1CD = hd1CD - .1;
hd2CD = hd2CD - .1;
hd3CD = hd3CD - .1;
hd4CD = hd4CD - .1;
}
Console.WriteLine(hd1CD);
Console.WriteLine(hd2CD);
Console.WriteLine(hd3CD);
Console.WriteLine(hd4CD);
if (hd4CD < 1.2 || hd1CD < 1.2 || hd2CD < 1.2 || hd3CD < 1.2 && hd4CD != 0 && hd1CD != 0 && hd2CD != 0 && hd3CD !=0)
The above is checking whether the variables hold 0, since im getting epsilon values my program cant run correctly...
{
//get minimum
hd1List.Add("extra" + superList.Min());
hd1CD = hd1CD - superList.Min();
hd2CD = hd2CD - superList.Min();
hd3CD = hd3CD - superList.Min();
hd4CD = hd4CD - superList.Min();
}
Summary: how do i re-arrange my code so that if i subtract .1 - .1, it = 0 and not a ridiculous number, i dont need advice, i need an example
You should not compare double values with ==. E.g. having code like
if (value==0) { /* do something here*/ }
is a bad idea if value is a double.
Instead you can do something like:
if (Math.Abs(value) < EPSILON) { /* do something here*/ }
where EPSILON is some small positive number/constant e.g. 1e-5.
Although you have a very good answer I thought I'd have a go at refactoring your code. Have a try of this:
List<string> hd1List = new List<string>();
double[] hdCDs = new double[4];
double EPSILON = 0.00000001;
Action<int, double, double, string> update = (i, v, d, t) =>
{
if (hdCDs[i] <= 0.0 && hdCDs.Take(i).All(x => x >= d))
{
hd1List.Add(t);
hdCDs[i] = v;
for (int x = 0; x <= i + 1; x++)
{
hdCDs[x] =- d;
}
}
Console.WriteLine(String.Join(Environment.NewLine, hdCDs));
};
update(0, 4.0, 0.7, "q");
update(1, 1.0, 0.7, "e");
update(2, 5.0, 0.2, "r");
update(3, 4.0, 0.1, "w");
if (hdCDs.Any(x => x < 1.2) && hdCDs.All(x => x <= EPSILON))
{
var min = superList.Min();
hd1List.Add("extra" + min);
for (int x = 0; x < hdCDs.Length; x++)
{
hdCDs[0] -= min;
}
}

How to do a loop to check all the variables at the same time for C#?

I want to loop all blueBallPosition[i] and greenBallPosition[i] except blueBallPosition[0] and greenBallPosition[0]. And also, I want to do an if else statement if all the variables except [0], are > 360. Whereas, [0] are < 360. I have tried to do a loop. However, if blueBallPosition[1] > 360 and greenBallPosition[1] > 360, pause will be set to true already. I want to loop through all the variables to make sure they are > 360, then pause set to true.
for (int i = 1; i < levelBall; i++)
{
if ((blueBallPosition[0] < 360) &&
(greenBallPosition[0] < 360) &&
(blueBallPosition[i] > 360) &&
(greenBallPosition[i] > 360))
{
pause = true;
}
}
For your information, levelBall is set as 4.
I have solved it. I just have to add a counter to it.
for (int i = 1; i < levelBall; i++)
{
if ((blueBallPosition[0] < 360) && (greenBallPosition[0] < 360) && (blueBallPosition[i] > 360) && (greenBallPosition[i] > 360))
{
count++;
}
}
if (count == (levelBall))
{
pause = true;
}
else
{
count = 0;
}
So you only want to pause if all balls (apart from 0) are > 360?
bool pause = false;
// Check ball[0] outside the loop for performance.
if (blueBallPosition[0] < 360 && greenBallPosition[0] < 360)
{
pause = true;
for (int i = 1; i < levelBall; i++)
{
if (blueBallPosition[i] <= 360) || (greenBallPosition[i] <= 360))
{
pause = false;
// You have found a ball that doesn't match, so no need
// to keep checking.
break;
}
}
}
Since you want to check if all the variables fulfill that condition you can't set it to true if one fulfills them, you can rewrite it to start as true, check if one of them does not fulfill it and then set it to false instead. If it still true afterwards you know what all the variables fulfill the condition.
pause = true;
for(...)
if(blue[0] >= 360) || green[0] >= 360 || blue[i] <= 360 || green[i] <= 360)
pause = false;
Try this:
if (blueBallPosition[0] < 360 &&
greenBallPosition[0] < 360 &&
blueBallPosition.Skip(1).All(b => b > 360) &&
greenBallPosition.Skip(1).All(b => b > 360))
pause = true;
you may try use linq to make it more readable:
if (blueBallPosition[0] < 360 && greenBallPosition[0] < 360)
{
var paulse = blueBallPosition.Select((b, idx) =>
new { Blue = b, Green = greenBallPosition[idx] })
.Skip(1).All(x => x.Blue > 360 && x.Green > 360);
}
pause = true;
for (int i = 1; i < levelBall; i++)
{
if ((blueBallPosition[0] >= 360) ||
(greenBallPosition[0] >= 360) ||
(blueBallPosition[i] <= 360) ||
(greenBallPosition[i] <= 360))
{
pause = false;
break;
}
}
First, move the checks that you can outside of the loop. Then assume that all checks pass and then undo that assumption if it turns out to be false:
if ((blueBallPosition[0] < 360) &&
(greenBallPosition[0] < 360))
{
pause = true;
for (int i = 1; i < levelBall; i++)
{
if((blueBallPosition[i] <= 360) ||
(greenBallPosition[i] <= 360))
{
pause = false;
}
}
}
very short code just like:
var pause = false;
if (blueBallPosition[0] < 360 && greenBallPosition[0] < 360)
{
pause = blueBallPosition.Any(b => b <= 360) || greenBallPosition.Any(b => b < 360);
}
Do not forget the using in namespace.
using System.Linq;
Alex and Rex the bad thing on your code u are using ALL = all means loop all elements if you modify your solution with Any will be better.

Fastest way to check if an array is sorted

Considering there is an array returned from a function which is of very large size.
What will be the fastest approach to test if the array is sorted?
A simplest approach will be:
/// <summary>
/// Determines if int array is sorted from 0 -> Max
/// </summary>
public static bool IsSorted(int[] arr)
{
for (int i = 1; i < arr.Length; i++)
{
if (arr[i - 1] > arr[i])
{
return false;
}
}
return true;
}
You will have to visit each element of the array to see if anything is unsorted.
Your O(n) approach is about as fast as it gets, without any special knowledge about the likely state of the array.
Your code specifically tests if the array is sorted with smaller values at lower indices. If that is not what you intend, your if becomes slightly more complex. Your code comment does suggest that is what you're after.
If you were to have special knowledge of the probable state (say, you know it's generally sorted but new data might be added to the end), you can optimize the order in which you visit array elements to allow the test to fail faster when the array is unsorted.
You can leverage knowledge of the hardware architecture to check multiple parts of the array in parallel by partitioning the array, first comparing the boundaries of the partition (fail fast check) and then running one array partition per core on a separate thread (no more than 1 thread per CPU core). Note though that if a array partition is much smaller than the size of a cache line, the threads will tend to compete with each other for access to the memory containing the array. Multithreading will only be very efficient for fairly large arrays.
Faster approach, platform target: Any CPU, Prefer 32-bit.
A sorted array with 512 elements: ~25% faster.
static bool isSorted(int[] a)
{
int j = a.Length - 1;
if (j < 1) return true;
int ai = a[0], i = 1;
while (i <= j && ai <= (ai = a[i])) i++;
return i > j;
}
Target: x64, same array: ~40% faster.
static bool isSorted(int[] a)
{
int i = a.Length - 1;
if (i <= 0) return true;
if ((i & 1) > 0) { if (a[i] < a[i - 1]) return false; i--; }
for (int ai = a[i]; i > 0; i -= 2)
if (ai < (ai = a[i - 1]) || ai < (ai = a[i - 2])) return false;
return a[0] <= a[1];
}
Forgot one, marginally slower than my first code block.
static bool isSorted(int[] a)
{
int i = a.Length - 1; if (i < 1) return true;
int ai = a[i--]; while (i >= 0 && ai >= (ai = a[i])) i--;
return i < 0;
}
Measuring it (see greybeard's comment).
using System; // ????????? DEBUG ?????????
using sw = System.Diagnostics.Stopwatch; // static bool abc()
class Program // { // a <= b <= c ?
{ // int a=4,b=7,c=9;
static void Main() // int i = 1;
{ // if (a <= (a = b))
//abc(); // {
int i = 512; // i++;
int[] a = new int[i--]; // if (a <= (a = c))
while (i > 0) a[i] = i--; // {
sw sw = sw.StartNew(); // i++;
for (i = 10000000; i > 0; i--) // }
isSorted(a); // }
sw.Stop(); // return i > 2;
Console.Write(sw.ElapsedMilliseconds); // }
Console.Read(); // static bool ABC();
} // {
// int[]a={4,7,9};
static bool isSorted(int[] a) // OP Cannon // int i=1,j=2,ai=a[0];
{ // L0: if(i<=j)
for (int i = 1; i < a.Length; i++) // if(ai<=(ai=a[i]))
if (a[i - 1] > a[i]) return false; // {i++;goto L0;}
return true; // return i > j;
} // }
}
Target: x64. Four cores/threads.
A sorted array with 100,000 elements: ~55%.
static readonly object _locker = new object();
static bool isSorted(int[] a) // a.Length > 3
{
bool b = true;
Parallel.For(0, 4, k =>
{
int i = 0, j = a.Length, ai = 0;
if (k == 0) { j /= 4; ai = a[0]; } // 0 1
if (k == 1) { j /= 2; i = j / 2; ai = a[i]; } // 1 2
if (k == 2) { i = j - 1; ai = a[i]; j = j / 2 + j / 4; } // 4 3
if (k == 3) { i = j - j / 4; ai = a[i]; j = j / 2; } // 3 2
if (k < 2)
while (b && i <= j)
{
if (ai <= (ai = a[i + 1]) && ai <= (ai = a[i + 2])) i += 2;
else lock (_locker) b = false;
}
else
while (b && i >= j)
{
if (ai >= (ai = a[i - 1]) && ai >= (ai = a[i - 2])) i -= 2;
else lock (_locker) b = false;
}
});
return b;
}
1,000,000 items?
if (k < 2)
while (b && i < j)
if (ai <= (ai = a[i + 1]) && ai <= (ai = a[i + 2]) &&
ai <= (ai = a[i + 3]) && ai <= (ai = a[i + 4])) i += 4;
else lock (_locker) b = false;
else
while (b && i > j)
if (ai >= (ai = a[i - 1]) && ai >= (ai = a[i - 2]) &&
ai >= (ai = a[i - 3]) && ai >= (ai = a[i - 4])) i -= 4;
else lock (_locker) b = false;
Let's forget percentages.
Original: 0.77 ns/item, now: 0.22 ns/item.
2,000,000 items? Four cores: 4 times faster.
Linq solution.
public static bool IsSorted<T>(IEnumerable<T> list) where T:IComparable<T>
{
var y = list.First();
return list.Skip(1).All(x =>
{
bool b = y.CompareTo(x) < 0;
y = x;
return b;
});
}
Here is my version of the function IsSorted
public static bool IsSorted(int[] arr)
{
int last = arr.Length - 1;
if (last < 1) return true;
int i = 0;
while(i < last && arr[i] <= arr[i + 1])
i++;
return i == last;
}
While this function is a bit faster than in the question, it will do fewer assignments and comparisons than anything has been posted so far. In the worst case, it does 2n+1 comparisons. It still can be improved if you can make a reasonable assumption about the nature of the data like minimum data size or array contains even number of elements.
The only improvement i can think of is check both ends of the array at the same time, this little change will do it in half time...
public static bool IsSorted(int[] arr)
{
int l = arr.Length;
for (int i = 1; i < l/2 + 1 ; i++)
{
if (arr[i - 1] > arr[i] || arr[l-i] < arr[l-i-1])
{
return false;
}
}
return true;
}
This is what I came up with and find works better particularly with greater sized arrays. The function is recursive and will be called for the very first time, say in a while loop like this
while( isSorted( yourArray, 0 )
The if statement checks if the bounds of the array have been reached.
The else if statement will call itself recursively and break at any time when the condition becomes false
public static bool IsSorted(int[] arr, int index)
{
if (index >= arr.Length - 1)
{
return true;
}
else if ((arr[index] <= arr[ index + 1]) && IsSorted(arr, index + 1))
{
return true;
}
else
{
return false;
}
}
If the order doesn't matter(descending or ascending).
private bool IsSorted<T>(T[] values) where T:IComparable<T>
{
if (values == null || values.Length == 0) return true;
int sortOrder = 0;
for (int i = 0; i < values.Length - 1; i++)
{
int newSortOrder = values[i].CompareTo(values[i + 1]);
if (sortOrder == 0) sortOrder = newSortOrder;
if (newSortOrder != 0 && sortOrder != newSortOrder) return false;
}
return true;
}
The question that comes to my mind is "why"?
Is it to avoid re-sorting an already-sorted list? If yes, just use Timsort (standard in Python and Java). It's quite good at taking advantage of an array/list being already sorted, or almost sorted. Despite how good Timsort is at this, it's better to not sort inside a loop.
Another alternative is to use a datastructure that is innately sorted, like a treap, red-black tree or AVL tree. These are good alternatives to sorting inside a loop.
This might not be the fastest but it's the complete solution. Every value with index lower than i is checked against the current value at i. This is written in php but can easily be translated into c# or javascript
for ($i = 1; $i < $tot; $i++) {
for ($j = 0; $j <= $i; $j++) {
//Check all previous values with indexes lower than $i
if ($chekASCSort[$i - $j] > $chekASCSort[$i]) {
return false;
}
}
}

Categories

Resources