I am trying to create an application to record the time elapsed per machine using simple arithmetic operations.
Using console application, with parameters of number of loop and the threads to use with the code below:
public static Int64 IterationCount { get; set; }
static void Main(string[] args)
{
int iterations = int.Parse(args[0]);
int threads = int.Parse(args[1]);
IterationCount = iterations * 1000000000;
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < threads; i++)
{
Task.Factory.StartNew(() => Calculate());
Task.WaitAll();
}
sw.Stop();
Console.WriteLine("Elapsed={0}", sw.Elapsed);
}
And my Calculate method:
private static void Calculate()
{
for (int i = 0; i < IterationCount; i++)
{
a = 1 + 2;
b = 1 - 2;
c = 1 * 2;
a = 1 / 2;
}
}
Now I think this is not working because the result of my elapsed time when I entered 10 iterations (I am multiplying the first parameter to 1 billion: 10 * 1,000,000,000) and 4 threads is:
00:00:00:0119747
Any thing I missed?
Your call to Task.WaitAll() has no effect as the signature of the function is
public static void WaitAll(params Task[] tasks).
You see, you can supply a variable count of Tasks to wait for and you call this function with no task; so it will not wait at all.
If you replace your code by the following, you will see the effect.
Task[] tasks = new Task[threads];
for (int i = 0; i < threads; i++)
{
tasks[i] = Task.Factory.StartNew(() => Calculate());
}
Task.WaitAll(tasks);
Turns out my comment is accurate. If I copy the contents of your Calculate method into Visual Studio:
private static void Calculate()
{
for (int i = 0; i < IterationCount; i++)
{
a = 1 + 2;
b = 1 - 2;
c = 1 * 2;
d = 1 / 2;
}
}
after compilation, the generated C# code looks like this:
private static void Calculate()
{
for (int i = 0; i < Program.IterationCount; i++)
{
Program.a = 3;
Program.b = -1;
Program.c = 2;
Program.d = 0;
}
}
Instead, you're going to have to make one of the constants into a variable:
private static void Calculate()
{
int x = 1;
for (int i = 0; i < IterationCount; i++)
{
a = x + 2;
b = x - 2;
c = x * 2;
d = x / 2;
}
}
This code becomes:
private static void Calculate()
{
int x = 1;
for (int i = 0; i < Program.IterationCount; i++)
{
Program.a = x + 2;
Program.b = x - 2;
Program.c = x * 2;
Program.d = x / 2;
}
}
Related
I recently got introduced to the concept of tail-call optimization and as far as I can read it's not inherently supported in the .NET compiler but there is a workaround called "Trampolining" which I've not made use of yet.
How can it be my "SumRecTail" benchmarks as slightly faster than my "SumRec" function if it's not supported? Given I don't have an error in my benchmarking...
public class Program
{
private static readonly int n = 100;
private static readonly int[] a = Enumerable.Range(0, n).ToArray();
static void Main(string[] args)
{
Mark("Marking regular recursion", SumRec);
Mark("Marking tail recursion", SumRecTail);
Console.ReadKey();
}
public static double Mark(string description, Func<int, double> method)
{
int noOfRuns = 30;
int count = 100_000;
double st = 0.0, sst = 0.0, dummy = 0.0;
Console.WriteLine(description);
for (int j = 0; j < noOfRuns; j++)
{
Timer t = new Timer();
for (int i = 0; i < count; i++)
{
dummy += method(n);
}
double time = t.CheckNanoSeconds() / count;
st += time;
sst += time * time;
}
double mean = st / noOfRuns, sdev = Math.Sqrt((sst - mean * mean * noOfRuns) / (noOfRuns - 1));
Console.WriteLine("avg {0} ns, {1} sdev", Math.Round(mean, 5), Math.Round(sdev, 5));
return dummy / noOfRuns;
}
public static double Mark(string description, Func<int, int, double> method)
{
int noOfRuns = 30;
int count = 100_000;
double st = 0.0, sst = 0.0, dummy = 0.0;
Console.WriteLine(description);
for (int j = 0; j < noOfRuns; j++)
{
Timer t = new Timer();
for (int i = 0; i < count; i++)
{
dummy += method(n, 0);
}
double time = t.CheckNanoSeconds() / count;
st += time;
sst += time * time;
}
double mean = st / noOfRuns, sdev = Math.Sqrt((sst - mean * mean * noOfRuns) / (noOfRuns - 1));
Console.WriteLine("avg {0} ns, {1} sdev", Math.Round(mean, 5), Math.Round(sdev, 5));
return dummy / noOfRuns;
}
private static double SumRecTail(int start, int sum)
{
return start == 0 ? sum : SumRecTail(start - 1, sum + start);
}
private static double SumRec(int end)
{
return end > 0 ? SumRec(end - 1) + end : 0;
}
}
The timer class:
public class Timer
{
private readonly Stopwatch StopWatch = null;
public Timer()
{
StopWatch = Stopwatch.StartNew();
}
public double CheckNanoSeconds()
{
return StopWatch.Elapsed.TotalMilliseconds * 1000000;
}
}
Output:
Marking regular recursion
avg 2044,21167 ns, 621,95915 sdev
Marking tail recursion
avg 1857,5378 ns, 69,5234 sdev
I have console application with numerical calculation, which I am trying to parallel using the ThreadPool.
I got object state as class (simple-data-passing):
public class DataContainer
{
public double[,] Exa;
public double[] EQ;
public int iStart;
public int iEnd;
}
Definition for WaitCallback
private void Calculate(object state)
{
DataContainer data = state as DataContainer;
for (int m = data.iStart; m < data.iEnd; m++)
{
double temp= 0.0;
for (int i = 0; i < 500000; i++)
{
for (int j = i + 1; j < 500000; j++)
{
//Some-Long-Calculation based on data.Exa-around 200 math operation with results of double EQC
if (EQC> temp) { temp= EQC; } //line performance issue-temp is declared in first for-loop block;
}
}
}
}
Execution:
WaitCallback waitCallback = Calculate;
const int numberOfThreads = 100;
ThreadPool.SetMaxThreads(30, 100);
for (int i = 0; i < numberOfThreads; i++)
{
DataContainer tempContainer = new DataContainer();
tempContainer.Exa = Exa;
tempContainer.EQ = EQ;
tempContainer.iStart = CalculateStart(i);
tempContainer.iEnd = CalculateEnd(i);
ThreadPool.QueueUserWorkItem(waitCallback, tempContainer);
}
int numberOfTotalThreads = 0;
int numberOfMaxThreads = 0;
int numberOfWorkingThreads = 0;
int temp = 0;
//do-while - waiting to finish all calculation
do
{
ThreadPool.GetAvailableThreads(out numberOfTotalThreads, out temp);
ThreadPool.GetMaxThreads(out numberOfMaxThreads, out temp);
numberOfWorkingThreads = numberOfMaxThreads - numberOfTotalThreads;
Console.WriteLine("Number of working threads {0}", numberOfWorkingThreads);
Thread.Sleep(1000);
} while (numberOfWorkingThreads > 0);
So one marked line:
if (EQC> temp) { temp= EQC; }
Time exeuction of program slow down from 40s to 600s.
Could you advice how these line should be written to avoid that problem?
I am writing a program to to calculate a specific value in Fibonacci sequence. The recursive method works perfectly, but when I try to use for loop, it doesn't work so well:
class Program
{
static int loopF(int n)
{
int result=0;
if (n == 1)
{
result = n;
}
else if (n == 2)
{
result = n;
}
else if (n>2)
{
int S1 = 1; int S2 = 2;
for (int i = 3; i>n; i++) {
result = S1 + S2;
S1 = S2;
S2 = result;
}
}
else{
Console.WriteLine("Input Error");
}
return (result);
}
static void Main()
{
Console.WriteLine(loopF(10)); //it gives me 0; wrong
Console.WriteLine(loopF(1)); //it gives me 1; correct.
}
}
Does anybody know where I go wrong? Thanks in advance.
Your loop is not executing
for (int i = 3; i>n; i++)
Variable i starts at 3 - in your test case n = 10.
(10 < 3) = false so the loop does not execute.
try using less than instead
for (int i = 3; i < n; i++)
Your loop's exit condition is wrong. It should be
for (int i = 3; i < n ; i++) { ...
I have a one assignment
I have to make one dimension array with 20 numbers - first 10 numbers are from 1 do 10. others 10 numbers I have to get in method called Dopolni - where I have to sum together array with one another like - p11 = p0+p1, p12 = p1+p2, p14 = p2+p3 and so on - I dont know how to arrange it to get those other 10 numbers - help please
my code till now is
static void Dopolni(int[] p)
{
for (int i = 11; i < 20; i++)
{
p[i] = p[i] + 1;
}
}
static void Main(string[] args)
{
int[] p = new int[20];
for (int i = 1; i < 20; i++)
{
if (i <= 10)
{
p[i] += i;
}
Console.WriteLine("{0}", p[i]);
}
Dopolni(p);
Console.WriteLine(p);
Console.ReadKey(true);
}
All numbers I have to write out in main window. Hope someone can help out
The indices of the first 10 numbers range from 0 to 9, the others from 10 to 19. But since you always sum two consecutive numbers, you will only get 9 sums! In order to get 10 sums, you could start by summing 0 with p[0]:
int previous = 0;
for (int i = 0; i < 10; i++) {
p[i + 10] = previous + p[i];
previous = p[i];
}
public static void Main()
{
int[] p = new int[20];
for (int i = 0; i < 10; i++)
{
p[i] = i + 1;
ยจ
Console.WriteLine(p[i]);
}
Dopolni(p);
}
static void Dopolni(int[] p)
{
for (int i = 10; i < 20; i++)
{
p[i] = p[i - 10] + p[i - 9];
Console.WriteLine(p[i]);
}
}
This looks like trouble:
int[] p = new int[20];
Console.WriteLine(p);
What you want is to loop through p and print each element, not rely on the array implementation of ToString().
Try:
foreach (var n in p)
Console.WriteLine(n);
Do you need to have it in a function? Its really quite simple...
Notice I use 'out int[]', thats what your missing in your code. Out specifies you want in/out param, not just in ;)
static void Main()
{
int[] p = new int[20];
// First 10 numbers
for (int i = 0; i < 10; i++)
p[i] = i + 1;
Dolpini(out p);
foreach (int m in p)
Console.WriteLine(m);
}
static void Dolpini(out int[] numbers)
{
// Next 10 numbers
for (int k = 10; k < 20; k++)
p[k] = p[k-10] + p[k-9];
}
In Code Complete 2 (page 601 and 602) there is a table of "Cost of Common Operations".
The baseline operation integer assignment is given a value 1 and then the relative time for common operations is listed for Java and C++. For example:
C++ Java
Integer assignment 1 1
Integer division 5 1.5
Floating point square root 15 4
The question is has anyone got this data for C#? I know that these won't help me solve any problems specifically, I'm just curious.
I implemented some of the tests from the book. Some raw data from my computer:
Test Run #1:
TestIntegerAssignment 00:00:00.6680000
TestCallRoutineWithNoParameters 00:00:00.9780000
TestCallRoutineWithOneParameter 00:00:00.6580000
TestCallRoutineWithTwoParameters 00:00:00.9650000
TestIntegerAddition 00:00:00.6410000
TestIntegerSubtraction 00:00:00.9630000
TestIntegerMultiplication 00:00:00.6490000
TestIntegerDivision 00:00:00.9720000
TestFloatingPointDivision 00:00:00.6500000
TestFloatingPointSquareRoot 00:00:00.9790000
TestFloatingPointSine 00:00:00.6410000
TestFloatingPointLogarithm 00:00:41.1410000
TestFloatingPointExp 00:00:34.6310000
Test Run #2:
TestIntegerAssignment 00:00:00.6750000
TestCallRoutineWithNoParameters 00:00:00.9720000
TestCallRoutineWithOneParameter 00:00:00.6490000
TestCallRoutineWithTwoParameters 00:00:00.9750000
TestIntegerAddition 00:00:00.6730000
TestIntegerSubtraction 00:00:01.0300000
TestIntegerMultiplication 00:00:00.7000000
TestIntegerDivision 00:00:01.1120000
TestFloatingPointDivision 00:00:00.6630000
TestFloatingPointSquareRoot 00:00:00.9860000
TestFloatingPointSine 00:00:00.6530000
TestFloatingPointLogarithm 00:00:39.1150000
TestFloatingPointExp 00:00:33.8730000
Test Run #3:
TestIntegerAssignment 00:00:00.6590000
TestCallRoutineWithNoParameters 00:00:00.9700000
TestCallRoutineWithOneParameter 00:00:00.6680000
TestCallRoutineWithTwoParameters 00:00:00.9900000
TestIntegerAddition 00:00:00.6720000
TestIntegerSubtraction 00:00:00.9770000
TestIntegerMultiplication 00:00:00.6580000
TestIntegerDivision 00:00:00.9930000
TestFloatingPointDivision 00:00:00.6740000
TestFloatingPointSquareRoot 00:00:01.0120000
TestFloatingPointSine 00:00:00.6700000
TestFloatingPointLogarithm 00:00:39.1020000
TestFloatingPointExp 00:00:35.3560000
(1 Billion Tests Per Benchmark, Compiled with Optimize, AMD Athlon X2 3.0ghz, using Jon Skeet's microbenchmarking framework available at http://www.yoda.arachsys.com/csharp/benchmark.html)
Source:
class TestBenchmark
{
[Benchmark]
public static void TestIntegerAssignment()
{
int i = 1;
int j = 2;
for (int x = 0; x < 1000000000; x++)
{
i = j;
}
}
[Benchmark]
public static void TestCallRoutineWithNoParameters()
{
for (int x = 0; x < 1000000000; x++)
{
TestStaticRoutine();
}
}
[Benchmark]
public static void TestCallRoutineWithOneParameter()
{
for (int x = 0; x < 1000000000; x++)
{
TestStaticRoutine2(5);
}
}
[Benchmark]
public static void TestCallRoutineWithTwoParameters()
{
for (int x = 0; x < 1000000000; x++)
{
TestStaticRoutine3(5,7);
}
}
[Benchmark]
public static void TestIntegerAddition()
{
int i = 1;
int j = 2;
int k = 3;
for (int x = 0; x < 1000000000; x++)
{
i = j + k;
}
}
[Benchmark]
public static void TestIntegerSubtraction()
{
int i = 1;
int j = 6;
int k = 3;
for (int x = 0; x < 1000000000; x++)
{
i = j - k;
}
}
[Benchmark]
public static void TestIntegerMultiplication()
{
int i = 1;
int j = 2;
int k = 3;
for (int x = 0; x < 1000000000; x++)
{
i = j * k;
}
}
[Benchmark]
public static void TestIntegerDivision()
{
int i = 1;
int j = 6;
int k = 3;
for (int x = 0; x < 1000000000; x++)
{
i = j/k;
}
}
[Benchmark]
public static void TestFloatingPointDivision()
{
float i = 1;
float j = 6;
float k = 3;
for (int x = 0; x < 1000000000; x++)
{
i = j / k;
}
}
[Benchmark]
public static void TestFloatingPointSquareRoot()
{
double x = 1;
float y = 6;
for (int x2 = 0; x2 < 1000000000; x2++)
{
x = Math.Sqrt(6);
}
}
[Benchmark]
public static void TestFloatingPointSine()
{
double x = 1;
float y = 6;
for (int x2 = 0; x2 < 1000000000; x2++)
{
x = Math.Sin(y);
}
}
[Benchmark]
public static void TestFloatingPointLogarithm()
{
double x = 1;
float y = 6;
for (int x2 = 0; x2 < 1000000000; x2++)
{
x = Math.Log(y);
}
}
[Benchmark]
public static void TestFloatingPointExp()
{
double x = 1;
float y = 6;
for (int x2 = 0; x2 < 1000000000; x2++)
{
x = Math.Exp(6);
}
}
private static void TestStaticRoutine() {
}
private static void TestStaticRoutine2(int i)
{
}
private static void TestStaticRoutine3(int i, int j)
{
}
private static class TestStaticClass
{
}
Straight from the source, Know what things cost.
IIRC Rico Mariani had relative measures as the ones you asked for on his blog, I can't find it anymore, though (I know it's in one of thoe twohudnred "dev" bookmarks...)
It's a reasonable question, but nearly every performance problem I've seen, especially in Java and C# boiled down to:
too many layers of abstraction, and
reliance on event-based notification-style coding.
which have little or nothing to do with basic operations.
The problem with abstraction is it is fine until the workload gets heavy. Each layer usually exacts a small performance penalty, and these accumulate in a compounded fashion. At that point you start needing workarounds. (I think StringBuilder is an example of such a workaround.)
The problem with event-based notification-style coding (as opposed to simpler data structures kept consistent by a periodic process) is that what can seem like simple actions, such as setting a property to a value, can result in a ripple effect of actions throughout the data structure doing far more than one might expect.