I've largely self taught myself C# code, I took a class in college that didnt help much...sure learned how to follow a book. So i've created tools here and there learning by example online. Stackoverflow is my favorite site for that, usually the community is helpful...
Anyway my question is this, im creating a WPF program that does multiple calculations on a number of decimals, the I've been getting by reusing the same code calculation over an over again, it works fine but I know there is a simpler way of doing it with much, much fewer lines. I seem to be missing that knowledge.
here is an example of how i would do things.
int int1 = 4;
int int2 = 2;
int int3 = 6;
int int4 = 8;
int calc1 = 0;
int calc2 = 0;
int calc3 = 0;
calc = int1 * int4
calc2 = int1 * int2
calc3 = int3 * int3
if (calc >= calc3)
{
do something;
}
else
{
calc = 33
}
if (calc2 >= calc3)
{
do something;
}
else
{
calc2 = 33
}
if (calc3 >= calc2)
{
do something;
}
else
{
calc3 = 33
}
if (calc3 >= calc)
{
do something;
}
else
{
calc2 = 33
}
I hope that is clear enough.. I can repeat the code but I am just unsure how to use C# better, I know it has built in ways of reducing the repeating code, just dont know how to find them.
Any help or examples are appreciated.
The simplest solution that pops out to me is to turn it into a method. (I will leave the access modifier for the function up to you...it depends on where you will be reusing this code)
int CustomCompare(int leftHandSide, int rightHandSide)
{
int calc;
if (leftHandSide >= rightHandside)
{
do something;
}
else
{
leftHandSide= 33
}
return leftHandSide
}
You would just pass in your variables:
calc = CustomCompare(calc, calc3)
You could even change the do something portion to be a custom action that you pass in if you want. Take a look at Action in MSDN
int CustomCompare(int leftHandSide, int rightHandSide, Action doSomething)
{
int calc;
if (leftHandSide >= rightHandside)
{
doSomething();
}
else
{
leftHandSide= 33
}
return leftHandSide
}
...
calc = CustomCompare(calc, calc3,
()=>{do some stuff that will be executed inside the method});
And Func can allow you to return a value from that doSomething action
The simplest way to reuse code among methods of the same class like that is to define a private method for that calculation. This way you'd be able to reference that code by calling a method, rather than by copy-pasting some code. In fact, every time you copy-paste, you know you're missing a method.
If you need to share code among related classes, you can make a protected method in the base class.
Finally, for project-wide "horizontal" reuse you can define a static helper class, and your methods to it as public static. This way every class in your project would be able to reuse your calculation.
How about creating a private method within your class, then call the method when you need a calculation done. This eliminates rewriting code over and over again.
Example:
int int1 = 4;
int calc1 = 0;
Calculation(int1, calc1);
int int2 = 2;
int calc2 = 0;
Calculation(int2, calc2);
//private method
private Calculation(int integer, int calculation)
{
//calculate
}
side note: I prefer to arrange all variables first, then act (function calls, etc.) on it (based on Arrange-Act-Assert associated with unit testing). However, I did it this way to emphasize my point.
Err.... call a function?
doCalc(4, 2, 6, 8)
static public void doCalc(int int1, int int2, int int3, int int4)
{
int calc1 = int1 * int4
int calc2 = int1 * int2
int calc3 = int3 * int3
if (calc >= calc3)
{
do something;
}
else
{
calc = 33
}
if (calc2 >= calc3)
{
do something;
}
else
{
calc2 = 33
}
if (calc3 >= calc2)
{
do something;
}
else
{
calc3 = 33
}
if (calc3 >= calc)
{
do something;
}
else
{
calc2 = 33
}
}
also, mind the indentations. when you start a new scope, add a few spaces to what's inside it.
Related
I'm implementing a caching table to avoid having to perform a costly operation that creates a generic object from a set of parameters describing it. Once an object is requested, an hash of these parameters is computed, and a Dictionary containing the already created objects is queried to check if a copy has already been created, in which case its returned without the need of creating it again.
My problem lies in the fact that since the parameters describing these objects can be many, collisions in the hashing function are unavoidable (and too frequent), but on the other hand retrieving these objects is a performance-critical operation and i cannot afford full comparisons on all existing descriptions to search among already created objects.
I've tried to solve with many different hashing functions but since the nature of the parameters is unknown the results are unreliable.
What solutions other than hashing are there to this caching problem, or can hashing be used differently to avoid conflicts?
C# description of the problem:
class ObjectDescriptor
{
// description made of a list of parameters of unknown type
public object[] Fields;
// hashing procedure that may have conflicts
public override int GetHashCode()
{
int hash = 1009;
for (int i = 0; i < Fields.Length; i++)
{
unchecked { hash = hash * 9176 + Fields[i].GetHashCode(); }
}
return hash;
}
}
abstract class ObjectCache<T>
{
private Dictionary<int, T> indexedObjects;
// this operation is called many times and must be fast
public T Get(ObjectDescriptor descr)
{
T cachedValue;
if(!indexedObjects.TryGetValue(descr.GetHashCode(), out cachedValue))
{
cachedValue = CreateObject(descr);
indexedObjects[descr.GetHashCode()] = cachedValue;
}
return cachedValue;
}
// costly operation
protected abstract T CreateObject(ObjectDescriptor desc);
}
I'll leave the solution I ended up using. This is based on the fact that conflicts can be avoided by storing whole values from multiple fields in a single hash where possible:
byte b1 = 42, b2 = 255;
int naiveHash = CombineHash(b1.GetHashCode(), b2.GetHashCode()); // will always have conflicts
int typeAwareHash = b1 << 8 + b2; // no conflicts
To know how many bits are required by a field I required the implementation of IObjectDescriptorField:
interface IObjectDescriptorField
{
int GetHashCodeBitCount();
}
I then updated the ObjectDescriptor class with an HashCodeBuilder class:
class ObjectDescriptor
{
public IObjectDescriptorField[] Fields;
public override int GetHashCode()
{
HashCodeBuilder hash = new HashCodeBuilder();
for (int i = 0; i < Fields.Length; i++)
{
hash.AddBits(Fields[i].GetHashCode(), Fields[i].GetHashCodeBitCount());
}
return hash.GetHashCode();
}
}
HashCodeBuilder stack up bits until all 32 are used, and then uses a simple hash combination function like before:
public class HashCodeBuilder
{
private const int HASH_SEED = 352654597;
private static int Combine(int hash1, int hash2)
{
return ((hash1 << 5) + hash1 + (hash1 >> 27)) ^ hash2;
}
private int hashAccumulator;
private int bitAccumulator;
private int bitsLeft;
public HashCodeBuilder()
{
hashAccumulator = HASH_SEED;
bitAccumulator = 0;
bitsLeft = 32;
}
public void AddBits(int bits, int bitCount)
{
if (bitsLeft < bitCount)
{
hashAccumulator = Combine(hashAccumulator, bitAccumulator);
bitsLeft = 32;
hashAccumulator = 0;
}
bitAccumulator = bitAccumulator << bitCount + bits;
bitsLeft -= bitCount;
}
public override int GetHashCode()
{
return Combine(hashAccumulator, bitAccumulator);
}
}
This solution of course still have conflicts if more then 32 bits are used, but it worked for me because many of the fields where just bools or Enums with few values, which greatly benefit to be combined like this.
I am writing some code on geometry processing, delaunay triangulation to be more specific, and I need it to be fast, so I use simple arrays of primitive as data structure to represent my triangulation information, here is a sample of it
private readonly float2[] points;
private readonly int[] pointsHalfEdgeStartCount;
private readonly int[] pointsIncomingHalfEdgeIndexes;
So let's say I want to iterate fast through all the incoming half-edge of the point of index p, I just do this using the precomputed arrays:
int count = pointsHalfEdgeStartCount[p * 2 + 1];
for (int i = 0; i < count; i++)
{
var e = pointsIncomingHalfEdgeIndexes[pointsHalfEdgeStartCount[p * 2] + i]
}
// pointsHalfEdgeStartCount[p * 2] is the start index
And this is fast enought, but does not feel safe or very clear. So I had the idea of wrapping my index into struct to make it clearer while retaining the performance, somthing like that:
public readonly struct Point
{
public readonly int index;
public readonly DelaunayTriangulation delaunay
public Point(int index, DelaunayTriangulation delaunay)
{
this.index = index;
this.delaunay = delaunay;
}
public int GetIncomingHalfEdgeCount() => delaunay.pointsEdgeStartCount[index * 2 + 1];
public HalfEdge GetIncomingHalfEdge(int i)
{
return new HalfEdge(
delaunay,
delaunay.pointsIncomingHalfEdgeIndexes[delaunay.pointsEdgeStartCount[index * 2] + i]
);
}
//... other methods
}
Then I can just do so:
int count = p.GetIncomingHalfEdgeCount();
for (int i = 0; i < count; i++)
{
var e = p.GetIncomingHalfEdge(i);
}
However it was kind of killing my performance, being a lot slower (around 10 times) on a benchmark I did, iterating over all the points and iterating over all their incoming half-edge. I guess because storing a reference to the delaunay triangulaiton in each point struct was an obvious waste and slowed down all the operations involving points, having twice the amount of data to move.
I could make the DelaunayTriangulation a static class but it was not practical for other reasons, so I did that:
public readonly struct Point
{
public readonly int index;
public Point(int index) => this.index = index;
public int GetIncomingHalfEdgeCount(DelaunayTriangulation delaunay) => delaunay.pointsEdgeStartCount[index * 2 + 1];
public HalfEdge GetIncomingHalfEdge(DelaunayTriangulation delaunay, int i)
{
return new HalfEdge(
delaunay.pointsIncomingHalfEdgeIndexes[delaunay.pointsEdgeStartCount[index * 2] + i]
);
}
//... other methods
}
I can just do so:
int count = p.GetIncomingHalfEdgeCount(delaunay);
for (int i = 0; i < count; i++)
{
var e = p.GetIncomingHalfEdge(delaunay, i);
}
It was quite a lot faster, but still 2.5 times slower than the first method using simple int. I wondered if it could be because I was getting int in the first method while I got HalfEdge struct in the other methods (A struct similar to the Point struct, contains only an index as data and a couple of methods), and difference between plain int and the faster struct vanished when I used the e int to instantiate a new HalfEdge struct. Though I am not sure why is that so costly.Weirder still, I explored for clarity sake the option of wrinting the method inside the Delaunay class instead of the Point struct:
// In the DelaunayTriangulation class:
public int GetPointIncomingHalfEdgeCount(Point p) => pointsEdgeStartCount[p.index * 2 + 1];
public HalfEdge GetPointIncomingHalfEdge(Point p, int i)
{
return new HalfEdge(
pointsIncomingHalfEdgeIndexes[pointsEdgeStartCount[p.index * 2] + i]
);
}
And I used it like this:
int count = delaunay.GetPointIncomingHalfEdgeCount(p);
for (int i = 0; i < count; i++)
{
var e = delaunay.GetPointIncomingHalfEdge(p, i);
}
And it was 3 times slower than the previous method! I have no idea why.
I tried to use disassembly to see what machine code was generated but I failed to do so (I am working with Unity3D). Am I condemned to rely on plain int in arrays and sane variable naming and to renounce on trying to have some compile-time type checking (is this int really a point index ?)
I am not even bringing up other questions such as, why it is even slower when I try to use IEnumerable types with yields like so:
public IEnumerable<int> GetPointIncomingHalfEdges(Point p)
{
int start = pointsEdgeStartCount[p.index * 2]; // this should be a slight optimization right ?
int count = pointsEdgeStartCount[p.index * 2 + 1];
for (int i = 0; i < count; i++)
{
yield pointsIncomingHalfEdgeIndexes[start + i];
}
}
I have added a compiler directive for aggressive inlining and it seems to make up for the discrepencies in time! For some reason the compiler fails to inline correctly for:
var e = delaunay.GetPointIncomingHalfEdge(p, i);
While it managed to do so with
var e = p.GetIncomingHalfEdge(delaunay, i);
Why ? I do not know. However It would be far easier if I was able to see how the code is compiled and I could not find how to do that. I will search that, maybe open another question and if I find a better explaination I will come back!
I'm new to threading, and the examples I see online construct threads by passing a void function. However, I want to speed up computation time by returning integer values in multiple threads. Here's the relevant part of my code:
public int CalculateLineWins5(List<List<Symbol>> _screen)
{
int wins = 0;
foreach (List<int> line in lines)
{
for (int i = 0; i < reelsNumber; i++)
{
lineSymbols[i] = _screen[i][line[i]];
}
//evaluate the win per line
wins += CalculateWinsInLine5(lineSymbols);
}
return wins;
}
public int CalculateWinsInLine5(List<Symbol> _symbolsOnLine)
{
// this function assumes there could be wilds on reel 1 (and there are only 5 reels)
int wildMultiplier = 1;
int win = 0;
Symbol symbol = _symbolsOnLine[0];
if (symbol.IsPayTableSymbol)
{
int oak = 0;
int oakWild = 0;
if (symbol.IsWild)
{
symbol = _symbolsOnLine[1];
if (symbol.IsWild)
{
oakWild++;
symbol = _symbolsOnLine[2];
if (symbol.IsWild)
{
oakWild++;
symbol = _symbolsOnLine[3];
if (symbol.IsWild)
{
oakWild++;
symbol = _symbolsOnLine[4];
if (symbol.IsWild)
{
oakWild++;
}
}
}
}
}
if (symbol.IsPayTableSymbol)
{
if (_symbolsOnLine[1].Index == symbol.Index || _symbolsOnLine[1].IsWild)
{
oak++;
if (_symbolsOnLine[1].IsWild) wildMultiplier *= _symbolsOnLine[1].Multiplier;
if (_symbolsOnLine[2].Index == symbol.Index || _symbolsOnLine[2].IsWild)
{
oak++;
if (_symbolsOnLine[2].IsWild) wildMultiplier *= _symbolsOnLine[2].Multiplier;
if (_symbolsOnLine[3].Index == symbol.Index || _symbolsOnLine[3].IsWild)
{
oak++;
if (_symbolsOnLine[3].IsWild) wildMultiplier *= _symbolsOnLine[3].Multiplier;
if (_symbolsOnLine[4].Index == symbol.Index || _symbolsOnLine[4].IsWild)
{
oak++;
if (_symbolsOnLine[4].IsWild) wildMultiplier *= _symbolsOnLine[4].Multiplier;
}
}
}
}
win += Mathf.Max(payTable[symbol.Index][oak], payTable[0][oakWild]) * wildMultiplier;
}
else
{
win += payTable[0][oakWild] * wildMultiplier;
}
}
return win;
}
Essentially, I want to run the computations within the foreach loop above in parallel. Typically that's going to be 40 to 50 iterations of the CalculateWinsInLine5 method, so I think I'd have to create 40 to 50 threads that are computed in parallel and each return an integer value. I just don't know how. Any help or feedback on how to approach this is welcome.
Edit: My project runs random simulations of slot machine payouts. In each simulation the program goes through a large number of iterations where it generates a random set of reel stops which generate a matrix of symbols (the screen). In each iteration, the screen pay is evaluated using the CalculateLineWins5 method.
This is actually a Unity project, and interestingly enough, I already tried using the Burst compiler which makes the simulations 1.5x slower, just like Parallel.ForEach.
I realise this is a non-specific code question. But I suspect that people with answers are on this forum.
I am receiving a large amount of records of < 100 bytes via TCP at a rate of 10 per millisecond.
I have to parse and process the data and that takes me 100 microseconds - so I am pretty maxed out.
Does 100 microseconds seem large?
Here is an example of the kind of processing I do with LINQ. It is really convenient - but is it inherently slow?
public void Process()
{
try
{
int ptr = PayloadOffset + 1;
var cPair = MessageData.GetString(ref ptr, 7);
var orderID = MessageData.GetString(ref ptr, 15);
if (Book.CPairs.ContainsKey(cPair))
{
var cPairGroup = Book.CPairs[cPair];
if (cPairGroup.BPrices != null)
{
cPairGroup.BPrices.ForEach(x => { x.BOrders.RemoveAll(y => y.OrderID.Equals(orderID)); });
cPairGroup.BPrices.RemoveAll(x => x.BOrders.Count == 0);
}
}
}
}
public class BOrderGroup
{
public double Amount;
public string OrderID;
}
public class BPriceGroup
{
public double BPrice;
public List<BOrderGroup> BOrders;
}
public class CPairGroup
{
public List<BPriceGroup> BPrices;
}
public static Dictionary<string, CPairGroup> CPairs;
As other have mentioned, LINQ is not inherently slow. But it can be slower than equivalent non-LINQ code (this is why Roslyn team has "Avoid LINQ" guide under coding conventions).
If this is your hot path and you need every microsecond than you should probably implement logic in such a way:
public void Process()
{
try
{
int ptr = PayloadOffset + 1;
var cPair = MessageData.GetString(ref ptr, 7);
var orderID = MessageData.GetString(ref ptr, 15);
if (Book.CPairs.TryGetValue(cPair, out CPairGroup cPairGroup) && cPairGroup != null)
{
for (int i = cPairGroup.BPrices.Count - 1; i >= 0; i--)
{
var x = cPairGroup.BPrices[i];
for (int j = x.BOrders.Count - 1; j >= 0; j--)
{
var y = x.BOrders[j];
if (y.OrderID.Equals(orderID))
{
x.BOrders.RemoveAt(j);
}
}
if (x.BOrders.Count == 0)
{
cPairGroup.BPrices.RemoveAt(i);
}
}
}
}
}
Main points:
Avoid double dictionary lookup by using TryGetValue
Single iteration over cPairGroup.BPrices
In place modification of structures by iterating backwards
This code should not contain any additional heap allocations
I've run into something really strange while working my way through some practice problems using dotnetfiddle. I have a program that applies a mathematical sequence (different calculations each step depending on whether the current step is even or odd):
using System;
public class Program
{
public static void Main()
{
int ceiling = 1000000;
int maxMoves = 0;
int maxStart = 0;
int testNumber;
for(int i = 1; i <= ceiling; i++){
testNumber = i;
int moves = 1;
while(testNumber != 1){
if(testNumber % 2 == 0){
testNumber = testNumber / 2;
moves++;
} else {
testNumber = (3 * testNumber) + 1;
moves++;
}
}
if(moves > maxMoves){
maxMoves = moves;
maxStart = i;
}
}
Console.WriteLine(maxStart);
Console.WriteLine(maxMoves);
}
}
As written, the execution time limit gets exceeded. However, if I change the declaration of test number to a long instead of an int, the program runs:
int maxMoves = 0;
int maxStart = 0;
**long** testNumber;
Why would making this change, which requires recasting i from an int to a long each increment of the for loop (at testNumber = i), be faster than leaving this as an int? Is performing the mathematical operations faster on a long value?
The reason seems to be an overflow. If you run that code enclosed in a
checked
{
// your code
}
you get an OverflowException when running with testNumber as int.
The reason is that eventually 3*testNumber+1 exceeds the boundary of an int. In an unchecked context this does not throw an exception, but leads to negative values for testNumber.
At this point your sequence (I think it's Collatz, right?) does not work anymore and the calculation takes (probably infinitly) longer, because you never reach 1 (or at least it takes you a whole lot more iterations to reach 1).