I have this ListView. My goal is to add / subtract a fixed time to all the times / selected times in the list. The thing is that there will be somewhat around 1000-3000 rows in it, so it takes some time. My goal is to make this as fast for the computer as possible.
Right now if I spam-run the function, it takes some time for the form to finish, and if I chose to do it with selected rows, half of them, then the form freezes for a while before finishing.
My code right now looks like this (here's a picture of the code for better view):
public void PlusMinus(bool plus)
{
int items_to_set = 0;
int msec_start = 0;
int msec_end = 0;
int msec_box = Convert.ToInt32(mskTime.Text.Substring(9, 3)) +
(Convert.ToInt32(mskTime.Text.Substring(6, 2)) * 1000) +
(Convert.ToInt32(mskTime.Text.Substring(3, 2)) * 60000) +
(Convert.ToInt32(mskTime.Text.Substring(0, 2)) * 3600000);
if (rbtnAll.Checked) { items_to_set = listSub.Items.Count; }
else { items_to_set = listSub.SelectedItems.Count; }
if (rbtnAll.Checked)
{
for (int i = 0; i < items_to_set; i++)
{
msec_start = Convert.ToInt32(listSub.Items[i].SubItems[1].Text.Substring(9, 3)) +
(Convert.ToInt32(listSub.Items[i].SubItems[1].Text.Substring(6, 2)) * 1000) +
(Convert.ToInt32(listSub.Items[i].SubItems[1].Text.Substring(3, 2)) * 60000) +
(Convert.ToInt32(listSub.Items[i].SubItems[1].Text.Substring(0, 2)) * 3600000);
msec_end = Convert.ToInt32(listSub.Items[i].SubItems[2].Text.Substring(9, 3)) +
(Convert.ToInt32(listSub.Items[i].SubItems[2].Text.Substring(6, 2)) * 1000) +
(Convert.ToInt32(listSub.Items[i].SubItems[2].Text.Substring(3, 2)) * 60000) +
(Convert.ToInt32(listSub.Items[i].SubItems[2].Text.Substring(0, 2)) * 3600000);
if (plus == true) { msec_start += msec_box; msec_end += msec_box; }
else { msec_start -= msec_box; msec_end -= msec_box; }
TimeSpan ts = TimeSpan.FromMilliseconds(msec_start);
listSub.Items[i].SubItems[1].Text = string.Format("{0:D2}:{1:D2}:{2:D2}:{3:D3}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds);
ts = TimeSpan.FromMilliseconds(msec_end);
listSub.Items[i].SubItems[2].Text = string.Format("{0:D2}:{1:D2}:{2:D2}:{3:D3}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds);
}
}
else
{
for (int i = 0; i < items_to_set; i++)
{
msec_start = Convert.ToInt32(listSub.Items[listSub.SelectedIndices[i]].SubItems[1].Text.Substring(9, 3)) +
(Convert.ToInt32(listSub.Items[listSub.SelectedIndices[i]].SubItems[1].Text.Substring(6, 2)) * 1000) +
(Convert.ToInt32(listSub.Items[listSub.SelectedIndices[i]].SubItems[1].Text.Substring(3, 2)) * 60000) +
(Convert.ToInt32(listSub.Items[listSub.SelectedIndices[i]].SubItems[1].Text.Substring(0, 2)) * 3600000);
msec_end = Convert.ToInt32(listSub.Items[listSub.SelectedIndices[i]].SubItems[2].Text.Substring(9, 3)) +
(Convert.ToInt32(listSub.Items[listSub.SelectedIndices[i]].SubItems[2].Text.Substring(6, 2)) * 1000) +
(Convert.ToInt32(listSub.Items[listSub.SelectedIndices[i]].SubItems[2].Text.Substring(3, 2)) * 60000) +
(Convert.ToInt32(listSub.Items[listSub.SelectedIndices[i]].SubItems[2].Text.Substring(0, 2)) * 3600000);
if (plus == true) { msec_start += msec_box; msec_end += msec_box; }
else { msec_start -= msec_box; msec_end -= msec_box; }
TimeSpan ts = TimeSpan.FromMilliseconds(msec_start);
listSub.Items[listSub.SelectedIndices[i]].SubItems[1].Text = string.Format("{0:D2}:{1:D2}:{2:D2}:{3:D3}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds);
ts = TimeSpan.FromMilliseconds(msec_end);
listSub.Items[listSub.SelectedIndices[i]].SubItems[2].Text = string.Format("{0:D2}:{1:D2}:{2:D2}:{3:D3}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds);
}
}
}
So is there some changes I could make that would be a somewhat big positive impact on the performance here?
Don't parse the strings at all. Instead, store the data as TimeSpans so there is no parsing at all.
Storing data as strings is bad-practice anyway because it clutters up your code with serialization and deserialization.
Where you store the data is not that important. You can use the object Tag property that is on most WinForms objects or store it elsewhere (maybe in a custom list or dictionary).
Also, your code looks highly redundant. Put common subexpressions into local variables. This will improve code quality and performance.
Related
I am baffled here. I have a function to return a double, sometimes it returns the correct value, but most of the times it return NaN. From my understanding NaN is returned when we have something like 0/0. Below is the function returning NaN, all it's variables are declared as doubles.
public double SuperiorValue(List<double> l)
{
valueKn[0] = 0;
valueKn[1] = 0;
valueKn[2] = 1.69;
valueKn[3] = 1.18;
valueKn[4] = 0.95;
valueKn[5] = 0.82;
valueKn[6] = 0.75;
valerKn[7] = 0.67;
valueKn[8] = 0.63;
valueKn[9] = 0.58;
valueKn[10] = 0.561;
valueKn[11] = 0.542;
valueKn[12] = 0.523;
valueKn[13] = 0.504;
valueKn[14] = 0.485;
valueKn[15] = 0.466;
valueKn[16] = 0.447;
valueKn[17] = 0.428;
valueKn[18] = 0.409;
valueKn[19] = 0.39;
valueKn[20] = 0.382;
Xm = (l.Sum()) / (l.Count);
for (int i = 0; i < l.Count; i++)
{
sumTemporary = l[i] - Xm;
sum = sum + sumTemporary;
}
kn = valueKn[l.Count];
sx = Math.Sqrt((1 / l.Count - 1) * (sum * sum));
Vx = sx / Xm;
Xksup = Xm * (1 + kn * Vx);
Xkinf = Xm * (1 - kn * Vx);
return Xksup;
}
What baffles me even more is that never is the list made of less than 3 elements and greater than 15, and it still often returns NaN but like I said sometimes it returns the correct value. Any thoughts on this ?
Look at
Math.Sqrt((1 / l.Count - 1) * (sum * sum))
The 1 / l.Count is an integer division, it will be 0 for all l.Count > 1 and then you are computing Sqrt(-1 * (sum * sum)) .
But (1.0 / l.Count - 1) would still be negative, you probably want (1.0 / (l.Count - 1))
The fix is then:
Math.Sqrt((1.0 / (l.Count - 1)) * (sum * sum))
I have 6 text boxes 2 for each type of bill that needs to be paid:
If I type a number into one of the two it updates the other with the difference:
The textboxes within the panels will always add to the same sum, if you change the value it automatically changes the value of its adjacent textbox, but the RENT textboxes are different.
I am trying to make it so the RENT textboxes take the (difference / 2) between the 3 pairs of other textboxes. so if patti pays 100$ more on the water bill than mike, mike has to pay that 100$ back on the rent which also subtracts 100$ off the rent from patti.
My current code results in this:
As you can see it doesn't update the rent textboxes properly. I have been trying to do this for a little over half a day, and I just can't see what I am doing wrong or what might be wrong with my math. Here is all of the code for my textboxes' textchanged events
private void txtMikeWater_TextChanged(object sender, EventArgs e)
{
double num;
bool parse = Double.TryParse(txtMikeWater.Text, out num);
if (txtMikeWater.Focused == true)
if (parse && num >= 0 && num <= expenses[2])
txtPattiWater.Text = (expenses[2] - num).ToString();
else
textBoxValidator(txtMikeWater, expenses[2], 0);
double difference = Math.Abs(num - Convert.ToDouble(txtPattiWater.Text)) / 2;
if (num > Convert.ToDouble(txtPattiWater.Text))
{
txtPattiRent.Text = ((expenses[0] / 2) + difference).ToString();
txtMikeRent.Text = ((expenses[0] / 2) - difference).ToString();
}
else
txtPattiRent.Text = ((expenses[0] / 2) - difference).ToString();
txtMikeRent.Text = ((expenses[0] / 2) + difference).ToString();
}
private void txtMikeElectric_TextChanged(object sender, EventArgs e)
{
double num;
bool parse = Double.TryParse(txtMikeElectric.Text, out num);
if (txtMikeElectric.Focused)
if (parse && num >= 0 && num <= expenses[3])
txtPattiElectric.Text = (expenses[3] - num).ToString();
double difference = Math.Abs(num - Convert.ToDouble(txtPattiElectric.Text)) / 2;
if (num > Convert.ToDouble(txtPattiElectric.Text))
{
txtPattiRent.Text = ((expenses[0] / 2) + difference).ToString();
txtMikeRent.Text = ((expenses[0] / 2) - difference).ToString();
}
else if (num < Convert.ToDouble(txtPattiElectric.Text))
{
txtPattiRent.Text = ((expenses[0] / 2) - difference).ToString();
txtMikeRent.Text = ((expenses[0] / 2) + difference).ToString();
}
}
private void txtMikeInternet_TextChanged(object sender, EventArgs e)
{
double num;
bool parse = Double.TryParse(txtMikeInternet.Text, out num);
if (txtMikeInternet.Focused)
if (parse && num >= 0 && num <= expenses[1])
txtPattiInternet.Text = (expenses[1] - num).ToString();
double difference = Math.Abs(num - Convert.ToDouble(txtPattiInternet.Text)) / 2;
if (num > Convert.ToDouble(txtPattiInternet.Text))
{
txtPattiRent.Text = ((expenses[0] / 2) + difference).ToString();
txtMikeRent.Text = ((expenses[0] / 2) - difference).ToString();
}
else if (num < Convert.ToDouble(txtPattiInternet.Text))
{
txtPattiRent.Text = ((expenses[0] / 2) - difference).ToString();
txtMikeRent.Text = ((expenses[0] / 2) + difference).ToString();
}
}
private void txtPattiWater_TextChanged(object sender, EventArgs e)
{
double num;
bool parse = Double.TryParse(txtPattiWater.Text, out num);
if (txtPattiWater.Focused == true)
if (parse && num >= 0 && num <= expenses[2])
txtMikeWater.Text = (expenses[2] - num).ToString();
double difference = Math.Abs(num - Convert.ToDouble(txtMikeWater.Text)) / 2;
if (num < Convert.ToDouble(txtMikeWater.Text))
{
txtPattiRent.Text = ((expenses[0] / 2) + difference).ToString();
txtMikeRent.Text = ((expenses[0] / 2) - difference).ToString();
}
else
{
txtPattiRent.Text = ((expenses[0] / 2) - difference).ToString();
txtMikeRent.Text = ((expenses[0] / 2) + difference).ToString();
}
}
private void txtPattiElectric_TextChanged(object sender, EventArgs e)
{
double num;
bool parse = Double.TryParse(txtPattiElectric.Text, out num);
if (txtPattiElectric.Focused)
if (parse && num >= 0 && num <= expenses[3])
txtMikeElectric.Text = (expenses[3] - num).ToString();
double difference = Math.Abs(num - Convert.ToDouble(txtMikeElectric.Text)) / 2;
if (num < Convert.ToDouble(txtMikeElectric.Text))
{
txtPattiRent.Text = ((expenses[0] / 2) + difference).ToString();
txtMikeRent.Text = ((expenses[0] / 2) - difference).ToString();
}
else if (num > Convert.ToDouble(txtMikeElectric.Text))
{
txtPattiRent.Text = ((expenses[0] / 2) - difference).ToString();
txtMikeRent.Text = ((expenses[0] / 2) + difference).ToString();
}
}
private void txtPattiInternet_TextChanged(object sender, EventArgs e)
{
double num;
bool parse = Double.TryParse(txtPattiInternet.Text, out num);
if (txtPattiInternet.Focused)
if (parse && num >= 0 && num <= expenses[1])
txtMikeInternet.Text = (expenses[1] - num).ToString();
double difference = Math.Abs(num - Convert.ToDouble(txtMikeWater.Text)) / 2;
if (num < Convert.ToDouble(txtMikeWater.Text))
{
txtPattiRent.Text = ((expenses[0] / 2) + difference).ToString();
txtMikeRent.Text = ((expenses[0] / 2) - difference).ToString();
}
else if (num > Convert.ToDouble(txtMikeWater.Text))
{
txtPattiRent.Text = ((expenses[0] / 2) - difference).ToString();
txtMikeRent.Text = ((expenses[0] / 2) + difference).ToString();
}
}
The expenses variable just stores the sum the pairs of the textboxes are supposed to have.
If anyone can please help I would appreciate it.
EDIT Just for some more clarity regarding the expenses variable.
expenses[0] = total rent
expenses[1] = total internet
expenses[2] = total water
expenses[3] = total electricity
Looks like your rent recalculations are only changing based on the difference of a single expense, not the total difference of all of them aggregated.
I suggest you create a single UpdateRent() method which sums up the total expenses paid for each person then calculates the difference:
private void txtPattiElectric_TextChanged(object sender, EventArgs e)
{
double num;
bool parse = Double.TryParse(txtPattiElectric.Text, out num);
if (txtPattiElectric.Focused)
if (parse && num >= 0 && num <= expenses[3])
txtMikeElectric.Text = (expenses[3] - num).ToString();
UpdateRent();
}
Your rent calculation might look like:
private void UpdateRent()
{
double pattiPaid = GetPattiWater() + GetPattiElectric() + GetPattiInternet();
double mikePaid = GetMikeWater() + GetMikeElectric() + GetMikeInternet();
double difference = pattiPaid - mikePaid;
double baseRent = GetRequiredMonthlyRent() / 2;
double pattiRent = baseRent - difference;
double mikeRent = baseRent + difference;
txtPattiRent.Text = pattiRent.ToString();
txtMikeRent.Text = mikeRent.ToString();
}
I also suggest you move most of the parsing/handling code to helper methods (indicated above) just to make it easier to track and debug the logic in general.
EDIT: Also note that the code eliminates the checking to see who paid more. It all works out in the math. For example, if Mike paid more, then difference is negative. Then that negative number is "subtracted" from Patti's base rent effectively increasing it. Feel free to re-introduce if checks to do the same work if you find it makes your code easier to understand, debug, and maintain.
EDITx2: It wasn't very clear in my original answer. Methods like GetPattiWater() and GetRequiredMonthlyRent() should simply read/return the current value:
private double GetPattiWater()
{
double amount;
Double.TryParse(txtPattiWater.Text, out amount);
return amount;
}
private double GetRequiredMonthlyRent()
{
return expenses[3];
}
You may need to do some special handling for temporary/blank/invalid non-parseable input in the text fields (the above would just return 0) but it might be simpler just to treat it as zero temporarily.
In order to parallelize and accelerate calculations I"ve splitted one long for-cycle by two short for-cycles using TPL, these parts are called PointGenerator and PointGenerator2 in my class bellow:
class CalcPiTPL
{
int n;
int totalCounter;
int counter1;
int counter2;
double aPi;
public StringBuilder Msg; // diagonstic message
Stopwatch stopWatch = new Stopwatch();
public void Init(int aN)
{
stopWatch.Start();
n = aN; // save total calculate-iterations amount
aPi = -1; // flag, if no any calculate-iteration has been completed
Msg = new StringBuilder("No any calculate-iteration has been completed");
}
public void Run()
{
if (n < 1)
{
Msg = new StringBuilder("Invalid N-value");
return;
}
Task[] tasks = new Task[2];
tasks[0] = Task.Factory.StartNew((obj) => { PointGenerator((int)obj); }, n);
tasks[1] = Task.Factory.StartNew((obj) => { PointGenerator2((int)obj); }, n);
Task.WaitAll(tasks[0], tasks[1]);
totalCounter = counter1 + counter2;
aPi = 4.0 * ((double)totalCounter / (double)n); // to calculate approximate Pi - value
Console.WriteLine(aPi);
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
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);
}
public double Done()
{
if (aPi > 0)
{
Msg = new StringBuilder("Calculates has been completed successful");
return aPi; // return gotten value
}
else
{
return 0; // no result
}
}
public void PointGenerator(int n)//FIRST PART OF ONE BIG FOR-CYCLE
{
double s = 0.125;
double sP = s / (n / 2);
double x = Math.Sqrt(sP);
for (double cX = 0; cX <= 0.25; cX += x)
{
for (double cY = 0; cY <= 0.5; cY += x)
{
if (((cX - 0.5) * (cX - 0.5) + (cY - 0.5) * (cY - 0.5)) < 0.25)
{
counter1++; // coordinate in a circle! mark it by incrementing N_0
}
}
}
}
public void PointGenerator2(int n)//SECOND PART OF ONE BIG FOR-CYCLE
{
double s = 0.125;
double sP = s / (n / 2);
double x = Math.Sqrt(sP);
for (double cX = 0.25; cX <= 0.5; cX += x)
{
for (double cY = 0; cY <= 0.5; cY += x)
{
if (((cX - 0.5) * (cX - 0.5) + (cY - 0.5) * (cY - 0.5)) < 0.25)
{
counter2++; // coordinate in a circle! mark it by incrementing N_0
}
}
}
}
}
And this is the same class without Tasks using(TPL), it has one long for-cycle:
class TCalcPi//unparallel calculating method
{
int N;
int n_0;
double aPi;
public StringBuilder Msg; // diagnostic message
Stopwatch stopWatch = new Stopwatch();
public void Init(int aN)
{
stopWatch.Start();
N = aN; // save total calculate-iterations amount
aPi = -1; // flag, if no any calculate-iteration has been completed
Msg = new StringBuilder("No any calculate-iteration has been completed");
}
public void Run()
{
if (N < 1)
{
Msg = new StringBuilder("Invalid N - value");
return;
}
double s = 0.25;
double sP = s / N;
double x = Math.Sqrt(sP);
for (double cX = 0; cX <= 0.5; cX += x)//ONE LONG FOR-CYCLE
{
for(double cY = 0; cY <= 0.5; cY += x)
{
if (((cX - 0.5) * (cX - 0.5) + (cY - 0.5) * (cY - 0.5)) < 0.25)
{
n_0++; // coordinate in a circle! mark it by incrementing N_0
}
}
}
aPi = 4.0 * ((double)n_0 / (double)N); // to calculate approximate Pi - value
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
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);
}
public double Done()
{
if (aPi > 0)
{
Msg = new StringBuilder("Calculates has been completed successful");
return aPi; // return gotten value
}
else
{
return 0; // no result
}
}
}
But unparallelized-class works faster, than parallelized(using TPL)class. How to fix it?
counter1 and counter2 most likely sit on the same cache line because they are adjacent in memory. This causes False Sharing. Probably, you are incrementing those counters very often. This pings the cacheline between the L1's of two cores for every alternation in time between the counters.
Separate them. As a proof of concept, like this:
int counter1;
long padding0, p1, p2, p3, p4, p5, p6, p7; //64 bytes padding
int counter2;
Let's hope the JIT does not reorder the fields. Maybe you need to use StructLayout.
Alternatively, make the counters local variables. Stack variables only have false sharing by extreme coincidence.
I have a pagination issue :
I have a large number of pages as results in my table ~50.000 pages and my pagination logic is something like :
1 2 3 ...50000
I would like to do something like :
1 2 3 10 100 500 1000 5000 10000 50000
And when i click for example 1111 :
1 1109 1110 1111 1112 1113 1114 1120 1200 1700 2200 3000 8000 10000 50000
so far I;ve tried something like this :
int Max_count = (int)Math.Floor(Math.Log10(totalPages) + 1);
for (int index = start; index <= end; index++)
{
if (index == pageNumber)
{
header.Items.Add(new PagingHeaderModelItem(PageHeaderItemType.CurrentPage, pageNumber));
}
else if (index == start)
{
header.Items.Add(new PagingHeaderModelItem(PageHeaderItemType.StartPage, 0));
}
else if (index == end)
{
header.Items.Add(new PagingHeaderModelItem(PageHeaderItemType.EndPage, totalPages - 1));
}
else if ((index == start + 1) && (index > 1))
{
header.Items.Add(new PagingHeaderModelItem(PageHeaderItemType.MorePages, -1));
}
else if ((index == end - 1) && (index < totalPages - 2))
{
header.Items.Add(new PagingHeaderModelItem(PageHeaderItemType.MorePages, -1));
}
else if ((index > 100) && (index > totalPages / 2))
{
header.Items.Add(new PagingHeaderModelItem(PageHeaderItemType.SimplePage, index));
}
else if ((pageNumber + 2 > index) && index + 10 < totalPages && !isSecond)
{
for (int temp = 1; temp < Max_count; temp++)
{
int power_var = (int)Math.Pow(10, temp);
int power_var_prev = (int)Math.Pow(10, temp - 1);
if ((pageNumber > power_var) || pageNumber < 10)
{
header.Items.Add(new PagingHeaderModelItem(PageHeaderItemType.SimplePage, power_var - 1));
header.Items.Add(new PagingHeaderModelItem(PageHeaderItemType.SimplePage, power_var - 1 + power_var_prev));
temp++;
}
}
isSecond = true;
}
else if (index - start < 3)
{
header.Items.Add(new PagingHeaderModelItem(PageHeaderItemType.SimplePage, index));
}
But i Feel like I'm not close to this at all. I'm not asking for a solution more of a hint or a formula I could use to do this by myself
LATER EDIT
The pattern should be like :
n-3, // 1 //1
n-2, // 2 //1109
n-1, // 3 //1110
**n**, // **4** //1111
n+1, //5 //1112
n+2, //6 //1113
n+3, //7 //1114
Math.Floor((index + 10)) / 10) * 10, //10 //1120
Math.Floor((index + 10)) / 10) * 10 +50, //60 //1170
Math.Floor((index + 100)) / 100) * 100, //100 //1200
Math.Floor((index + 100)) / 100) * 100+500,//600 //1700
Math.Floor((index + 1000)) / 1000) * 1000,//1000 //2000
Math.Floor((index + 1000)) / 1000) * 1000+5000,//6000/7000
....
Here's some code to print the desired values:
(it does print 1108 as well, but that should be easy enough to work around)
(changed +50, +500, etc. to +40, +400, etc. because I prefer that)
int min = 1, max = 50000;
if (val-3 > min)
Console.WriteLine(min);
for (int i = Math.Max(min, val-3); i <= Math.Min(max, val+3); i++)
Console.WriteLine(i);
int last = -1;
for (int i = 10; ; i *= 10)
{
int next = (val+3 + i) / i * i;
if (next > max)
break;
// prevent printing something like 90, 130, 100, 500 (100 won't print)
if (next > last)
Console.WriteLine(next);
next += 4*i;
if (next > max)
break;
Console.WriteLine(next);
last = next;
}
Live demo.
If you want to print it from the value to the minimum as well, it could be a simple case of copying the for-loop and inverting the values: (it will print the values from the largest, changing this will require a stack data structure)
for (int i = 10; ; i *= 10)
{
int next = (val-3 - i) / i * i;
if (next < min)
break;
if (next < last)
Console.WriteLine(next);
next -= 4*i;
if (next < min)
break;
Console.WriteLine(next);
last = next;
}
if (last != min)
Console.WriteLine(min);
Here's another idea:
Taking 1111 in 1..50000 as an example.
Take the 2 values before and the 2 values after - 1109, 1110, 1111, 1112, 1113.
Let's say we want an exponential growth towards the target, with 5 points in between.
The range of values upwards would be 50000 - 1113 = 48887 (starting from biggest value above).
Then we want to find x such that (5x)^2 = 48887. This is fairly easy to calculate, just square root 48887 and divide by 5 - sqrt(48887) / 5 = 44.22
Then the values would be:
1113 + (1 * 44.22) ^ 2 = 3068
1113 + (2 * 44.22) ^ 2 = 8934
1113 + (3 * 44.22) ^ 2 = 18712
1113 + (4 * 44.22) ^ 2 = 32400
1113 + (5 * 44.22) ^ 2 = 50000
Similarly for downwards.
You can probably base the number of values in between on how far the target is, if you wish.
If you'd prefer more round numbers, I'd have to think about that a bit more.
I have a C# .NET 2.0 script and I want to know why the following code would be faster than a do while loop of the same kind.
private double getStop(double avgPrice, bool longTrading)
{
double stopS = 0.0;
double stopL = 0.0;
for (int i = 0; i < 13; i++)
{
if (i == 0 || i == 12)
{
stopS = 0.0;
stopL = 0.0;
}
else
{
if ((lines[i] - ((lines[i] - lines[i - 1]) / 2)) < avgPrice && avgPrice < (lines[i + 1] - ((lines[i + 1] - lines[i]) / 2)))
{
if (avgPrice < lines[i])
{
stopL = (lines[i] - ((lines[i] - lines[i - 1]) / 2));
stopS = lines[i];
} else {
stopL = lines[i];
stopS = (lines[i + 1] - ((lines[i + 1] - lines[i]) / 2));
}
}
}
}
if (longTrading)
{
return stopL;
} else {
return stopS;
}
}
Also, would it be faster just to explicitly state each if statement instead of doing them inside of a for loop?
Being that this was answered so fast, why would this run far slower than the above code?
private double getStop(double avgPrice, bool longTrading)
{
double stopS = 0.0;
double stopL = 0.0;
for (int i = 0; i < 13; i++)
{
if (i == 0 || i == 12)
{
stopS = 0.0;
stopL = 0.0;
skip = true;
}
if (!skip && (lines[i] - ((lines[i] - lines[i - 1]) / 2)) < avgPrice && avgPrice < (lines[i + 1] - ((lines[i + 1] - lines[i]) / 2)))
{
if (avgPrice < lines[i])
{
stopL = (lines[i] - ((lines[i] - lines[i - 1]) / 2));
stopS = lines[i];
} else {
stopL = lines[i];
stopS = (lines[i + 1] - ((lines[i + 1] - lines[i]) / 2));
}
}
}
skip = false;
}
if (longTrading)
{
return stopL;
} else {
return stopS;
}
}
The performance difference should be negligible, but the for loop is clearer so I would go with that.
They should be essentially equivalent. Your 'for' loop gets evaluated as:
int i = 0;
while (i < 13)
{
//all other stuff
i++;
};
loop variations aren't too much different, it depends on the context and the programming language.
But my opinion is, for statement don't do until the constaint(s) is/are matched, therefore it should be faster than do/while.