Is numbers comparisons as uint faster than normal int in c# - c#

I was looking how some of the .Net core libraries were implemented and one of many things that caught my eye was that in Dictionary<TKey, TValue> class some numeric comparisons where done doing a casting to (uint) even though at my naive eyes this didn't impacted the logic.
For example on
do { // some magic } while (collisionCount <= (uint)entries.Length);
collisionCount was initialized at 0 and always incremented (collisionCount++) and thus entries being an array its length will not be negative either see source code
as opposed to
if ((uint)i >= (uint)entries.Length) { // some code }
source code line
where i could become negative in some occasions when doing the following, see debug img
i = entry.next;
and thus using it as positive would change the program flow (due to two's complement)
See an extract of the class code:
// Some code and black magic
uint hashCode = (uint)key.GetHashCode();
int i = GetBucket(hashCode);
Entry[]? entries = _entries;
uint collisionCount = 0;
if (typeof(TKey).IsValueType)
{
i--;
do
{
if ((uint)i >= (uint)entries.Length) // <--- Workflow impact
{
goto ReturnNotFound;
}
entry = ref entries[i];
if (entry.hashCode == hashCode && EqualityComparer<TKey>.Default.Equals(entry.key, key))
{
goto ReturnFound;
}
i = entry.next;
collisionCount++;
} while (collisionCount <= (uint)entries.Length);
}
// More cool stuffs
Is there any performace gain or what is the reason for this?

The linked Dictionary source contains this comment;
// Should be a while loop https://github.com/dotnet/runtime/issues/9422
// Test in if to drop range check for following array access
if ((uint)i >= (uint)entries.Length)
{
goto ReturnNotFound;
}
entry = ref entries[i];
The uint comparison here isn't faster, but it helps speed up the array access. The linked github issue talks about a limitation in the runtime compiler, and how this loop structure allows further optimisations. Since this uint comparison has been performed explicitly, the compiler can prove that 0 <= i < entries.Length. This allows the compiler to leave out the array boundary test and throw of IndexOutOfRangeException that would otherwise be required.
In other words, at the time this code was written, and performance profiling was performed. The compiler wasn't smart enough to make simpler, more readable code, run as fast as possible. So someone with a deep understanding of the limitations of the compiler tweaked the code to make it better.

Related

How to truncate an array in place in C#

I mean is it really possible? MSDN says that arrays are fixed-size and the only way to resize is "copy-to-new-place". But maybe it is possible with unsafe/some magic with internal CLR structures, they all are written in C++ where we have a full memory control and can call realloc and so on.
I have no code provided for this question, because I don't even know if it can exist.
I'm not talking about Array.Resize methods and so on, because they obviosly do not have needed behaviour.
Assume that we have a standard x86 process with 2GB ram, and I have 1.9GB filled by single array. Then I want to release half of it. So I want to write something like:
MagicClass.ResizeArray(ref arr, n)
And do not get OutOfMemoryException. Array.Resize will try to allocate another gigabyte of RAM and will fail with 1.9+1 > 2GB OutOfMemory.
You can try Array.Resize():
int[] myArray = new int[] { 1, 2, 3, 4 };
int myNewSize = 1;
Array.Resize(ref myArray, myNewSize);
// Test: 1
Console.Write(myArray.Length);
realloc will attempt to do the inplace resize - but it reserves the right to copy the whole thing elsewhere and return a pointer that's completely different.
Pretty much the same outward behaviour is exposed by .NET's List<T> class - which you should be using anyway if you find yourself changing array sizes often. It hides the actual array reference from you so that the change is propagated throughout all of the references to the same list. As you remove items from the end, only the length of the list changes while the inner array stays the same - avoiding the copying.
It doesn't release the memory (you can always do that explicitly with Capacity = XXX, but that makes a new copy of the array), but then again, unless you're working with large arrays, neither does realloc - and if you're working with large arrays, yada, yada - we've been there :)
realloc doesn't really make sense in the kind of memory model .NET has anyway - the heap is continously collected and compacted over time. So if you're trying to use it to avoid the copies when just trimming an array, while also keeping memory usage low... don't bother. At the next heap compaction, the whole memory above your array is going to be moved to fill in the blanks. Even if it were possible to do the realloc, the only benefit you have over simply copying the array is that you would keep your array in the old-living heap - and that isn't necessarily what you want anyway.
Neither array type in BCL supports what you want. That being said - you can implement your own type that would support what you need. It can be backed by standard array, but would implement own Length and indexer properties, that would 'hide' portion of array from you.
public class MyTruncatableArray<T>
{
private T[] _array;
private int _length;
public MyTruncatableArray(int size)
{
_array = new T[size];
_length = size;
}
public T this[int index]
{
get
{
CheckIndex(index, _length);
return _array[index];
}
set
{
CheckIndex(index, _length);
_array[index] = value;
}
}
public int Length
{
get { return _length; }
set
{
CheckIndex(value);
_length = value;
}
}
private void CheckIndex(int index)
{
this.CheckIndex(index, _array.Length);
}
private void CheckIndex(int index, int maxValue)
{
if (index < 0 || index > maxValue)
{
throw new ArgumentException("New array length must be positive and lower or equal to original size");
}
}
}
It really depend what exactly do need. (E.g. do you need to truncate just so that you can easier use it from your code. Or is perf/GC/memory consumption a concern? If the latter is the case - did you perform any measurements that proves standard Array.Resize method unusable for your case?)

Code Contracts: How to express these conditions?

I'm playing around with Code Contracts at the moment and I'm not completely sure whether the static methods of the Contract class are powerful enough to compete with mathematical notation of conditions.
Let's assume we got a simple factorial method
int Factorial(int n);
I would express the following conditions:
Precondition:
n >= 0
Postconditions:
Factorial(n) = 1, in case n = 0
Factorial(n) = n*(n-1)*...*1, in case n > 0
These conditions clearly specify the behavior of Factorial in a short and clean way. My question is, whether they can be expressed through Code Contracts.
The precondition is trivial:
Contract.Requires(n >= 0)
The conditional post condition might be expresses using
if(n==0)
Contract.Ensures(Contract.Result<int>() == 1);
if(n > 0)
...
But I don't like the way I need the "if" statement here as it makes the plain list of pre- and postconditions harder to read. I hoped we would have something like
Contract.Ensures(...).InCase(...);
And last but not least, I do not have any idea how to express this, which is a common notation regarding math:
n*(n-1)*...*1
Guess I would need some kind of loop, but this would copy the whole implementation. Is there any smart way to express such notations?
Thank you in advance.
What you are looking for are Unit Tests, not Code Contracts.
Tipically, checks like if n=0, then f(n) = 1 and if n=3, then f(n) = 6 are Test Cases that should be expressed as Unit Tests.
In your case, I think a suitable post condition would be something like "The result is always >= 1". And nothing more than that.
Assuming that your factorial class looks something like this:
public class Factorial
{
public int Compute(int n)
{
if (n == 0)
return 1;
return n * Compute(n - 1);
}
}
a suitable Unit Test written with the NUnit Framework would be:
[TestFixture]
public class FactorialTests
{
[TestCase(0, 1)]
[TestCase(1, 1)]
[TestCase(2, 2)]
[TestCase(7, 5040)]
[TestCase(10, 3628800)]
public void Compute_ReturnsCorrectResult(int n, int expectedResult)
{
var sut = new Factorial();
Assert.AreEqual(expectedResult, sut.Compute(n));
}
}
Update (after the comments)
Stating result >= 1 does not fully specify the algorithm.
I don't think the Code Contract's job is to specify the algorithm in detail. the algorithm is specified by the method.
If the Code Contract was a complex piece of logic like the method itself, then I guess we would need a Code Contract Contract to verify that the Code Contract performs the correct checks. This obviously leads to infinite recursion.
I didn't expect n*(n-1)*...*1 to be accepted by the compiler. But some generic range operator in a LINQ-flavoured way would surely be a gread addition, e.g. From(n).To(1).Product() or From(n).To(m).Sum()
If there was such a form of expressing factorials (and probably there is) you could certainly use it in your code, rather than the Code Contracts.
Update 2
Just for fun, I found a LINQ way of computing Factorials:
Enumerable.Range(1, n == 0 ? 1 : n).Aggregate((a, i) => a * i);
You could try to the following:
Contract.Ensures(Contract.Result<int>() == AlternativeFactorial(n));
where AlternativeFactorial is:
[Pure]
public static int AlternativeFactorial(int n)
{
if(n==0)
return 1;
if(n > 0)
{
//Alternative implementation.
}
}
Of course anything you use in a contract should be side-effect free (pure).
Now as far as the factorial implementation, I cannot come up with a more compact "alternative" implementation than w0lf's. What you should consider though is changing the return value of your method from int to BigInteger. Factorials can get very large very quickly. Also note that by adding a post-condition on the factorial value, you will pretty much double the time your method will take to return a result. This can be resolved by building CodeContracts only on the debug configuration.

The performance cost to using ref instead of returning same types?

Hi this is something that's really bothering me and I'm hoping someone has an answer for me. I've been reading about ref (and out) and I'm trying to figure out if I'm slowing down my code using refs. Commonly I will replace something like:
int AddToInt(int original, int add){ return original+add; }
with
void AddToInt(ref int original, int add){ original+=add; } // 1st parameter gets the result
because to my eyes this
AddToInt(ref _value, _add);
is easier to read AND code than this
_value = AddToInt(_value, _add);
I know precisely what I'm doing on the code using ref, as opposed to returning a value. However, performance is something I take seriously, and apparently dereferencing and cleanup is a lot slower when you use refs.
What I'd like to know is why every post I read says there is very few places you would typically pass a ref (I know the examples are contrived, but I hope you get the idea), when it seems to me that the ref example is smaller, cleaner and more exact.
I'd also love to know why ref really is slower than returning a value type - to me it would seem to me, if I was going to edit the function value a lot before returning it, that it would be quicker to reference the actual variable to edit it as opposed to an instance of that variable shortly before it gets cleaned from memory.
The main time that "ref" is used in the same sentence as performance is when discussing some very atypical cases, for example in XNA scenarios where the game "objects" are quite commonly represented by structs rather than classes to avoid problems with GC (which has a disproportionate impact on XNA). This becomes useful to:
prevent copying an oversized struct multiple times on the stack
prevent data loss due to mutating a struct copy (XNA structs are commonly mutable, against normal practice)
allow passing a struct in an an array directly, rather than ever copying it out and back in
In all other cases, "ref" is more commonly associated with an additional side-effect, not easily expressed in the return value (for example see Monitor.TryEnter).
If you don't have a scenario like the XNA/struct one, and there is no awkward side effect, then just use the return value. In addition to being more typical (which in itself has value), it could well involve passing less data (and int is smaller than a ref on x64 for example), and could require less dereferencing.
Finally, the return approach is more versatile; you don't always want to update the source. Contrast:
// want to accumulate, no ref
x = Add(x, 5);
// want to accumulate, ref
Add(ref x, 5);
// no accumulate, no ref
y = Add(x, 5);
// no accumulate, ref
y = x;
Add(ref y, x);
I think the last is the least clear (with the other "ref" one close behind it) and ref usage is even less clear in languages where it is not explicit (VB for example).
The main purpose of using the ref keyword is to signify that the variable's value can be changed by the function its being passed into. When you pass a variable by value, updates from within the function don't effect the original copy.
Its extremely useful (and faster) for situations when you want multiple return values and building a special struct or class for the return values would be overkill. For example,
public void Quaternion.GetRollPitchYaw(ref double roll, ref double pitch, ref double yaw){
roll = something;
pitch = something;
yaw = something;
}
This is a pretty fundamental pattern in languages that have unrestricted use of pointers. In c/c++ you frequently see primitives being passed around by value with classes and arrays as pointers. C# does just the opposite so 'ref' is handy in situations like the above.
When you pass a variable you want updated into a function by ref, only 1 write operation is necessary to give you your result. When returning values however, you normally write to some variable inside the function, return it, then write it again to the destination variable. Depending on the data, this could add unnecessary overhead. Anyhow, these are the main things that I typically consider before using the ref keyword.
Sometimes ref is a little faster when used like this in c# but not enough to use it as a goto justification for performance.
Here's what I got on a 7 year old machine using the code below passing and updating a 100k string by ref and by value.
Output:
iterations: 10000000
byref: 165ms
byval: 417ms
private void m_btnTest_Click(object sender, EventArgs e) {
Stopwatch sw = new Stopwatch();
string s = "";
string value = new string ('x', 100000); // 100k string
int iterations = 10000000;
//-----------------------------------------------------
// Update by ref
//-----------------------------------------------------
sw.Start();
for (var n = 0; n < iterations; n++) {
SetStringValue(ref s, ref value);
}
sw.Stop();
long proc1 = sw.ElapsedMilliseconds;
sw.Reset();
//-----------------------------------------------------
// Update by value
//-----------------------------------------------------
sw.Start();
for (var n = 0; n < iterations; n++) {
s = SetStringValue(s, value);
}
sw.Stop();
long proc2 = sw.ElapsedMilliseconds;
//-----------------------------------------------------
Console.WriteLine("iterations: {0} \nbyref: {1}ms \nbyval: {2}ms", iterations, proc1, proc2);
}
public string SetStringValue(string input, string value) {
input = value;
return input;
}
public void SetStringValue(ref string input, ref string value) {
input = value;
}
I have to agree with Ondrej here. From a stylistic view, if you start passing everything with ref you will eventually end up working with devs who will want to strangle you for designing an API like this!
Just return stuff from the method, don't have 100% of your methods returning void. What you are doing will lead to very unclean code and might confuse other devs who end up working on your code. Favour clarity over performance here, since you won't gain much in optomization anyway.
check this SO post: C# 'ref' keyword, performance
and this article from Jon Skeet: http://www.yoda.arachsys.com/csharp/parameters.html
in your case, using ref is a bad idea.
when using ref, the program will read a pointer off of the stack, than read the value the pointer is pointing at.
but if you were to pass by value it would only need to read the value off of the stack, basically reducing the amount of reads by half.
passing by reference should only be used for medium to large data structures like, for example, 3D models or arrays.
Using ref for basic datatypes is not a good idea.
Especially for simple methods which have few lines of code.
First off C# compiler will do lots of optimizations to make the code faster.
As per my benchmark https://rextester.com/CQJR12339 passing by ref has degraded the performance.
When a reference is passed , you are copying 8bytes as a pointer variable (assuming 64 bit processor) why not pass a 8Bytes double directly?
Pass by ref is useful in case of larger objects , For example a string which has lots of characters.
First, don't bother whether using ref is slower or faster. It's premature optimization. In 99.9999% cases you won't run into a situation this would cause a performance bottleneck.
Second, returning the result of the calculation as a return value as opposed to using ref is preferred because of the usual 'functional' nature of C-like languages. It leads to better chaining of statements/calls.
Update: Adding evidence from an actual performance benchmark, which shows the difference is ~1%, and hence readability over premature optimization is the suggested approach. Plus, ref turns out to be actually slower than a return value; however, as the difference is so small, repeated runs of the benchmark may end up opposite.
Results for .NET 6.0.7:
Method
Mean
Error
StdDev
AddToIntBase
375.6 us
5.36 us
4.18 us
AddToIntReturn
378.6 us
7.22 us
7.41 us
AddToIntReturnInline
375.5 us
4.84 us
4.04 us
AddToIntRef
383.7 us
5.92 us
5.25 us
AddToIntRefInline
384.2 us
7.29 us
8.96 us
Results for .NET 4.8 (because this is an 11-year-old question) are essentially the same:
Method
Mean
Error
StdDev
AddToIntBase
381.3 us
7.40 us
7.92 us
AddToIntReturn
380.8 us
7.00 us
6.55 us
AddToIntReturnInline
380.0 us
5.03 us
4.20 us
AddToIntRef
378.5 us
6.62 us
5.87 us
AddToIntRefInline
381.5 us
4.50 us
3.76 us
Benchmark code:
public class AddToIntBenchmark
{
[Benchmark]
public void AddToIntBase()
{
int result = 0;
for (int i = 0; i < 1_000_000; i++) result += i;
}
[Benchmark]
public void AddToIntReturn()
{
int result = 0;
for (int i = 0; i < 1_000_000; i++) result = AddToInt(result, i);
}
[Benchmark]
public void AddToIntReturnInline()
{
int result = 0;
for (int i = 0; i < 1_000_000; i++) result = AddToIntInline(result, i);
}
[Benchmark]
public void AddToIntRef()
{
int result = 0;
for (int i = 0; i < 1_000_000; i++) AddToInt(ref result, i);
}
[Benchmark]
public void AddToIntRefInline()
{
int result = 0;
for (int i = 0; i < 1_000_000; i++) AddToIntInline(ref result, i);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private int AddToIntInline(int original, int add) { return original + add; }
private int AddToInt(int original, int add) { return original + add; }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void AddToIntInline(ref int original, int add) { original += add; }
private void AddToInt(ref int original, int add) { original += add; }
}
Environment: .NET 6.0.7, Intel Xeon Gold 16-core 2.4 GHz, WS2019 virtual machine

Find sequence in IEnumerable<T> using Linq

What is the most efficient way to find a sequence within a IEnumerable<T> using LINQ
I want to be able to create an extension method which allows the following call:
int startIndex = largeSequence.FindSequence(subSequence)
The match must be adjacent and in order.
Here's an implementation of an algorithm that finds a subsequence in a sequence. I called the method IndexOfSequence, because it makes the intent more explicit and is similar to the existing IndexOf method:
public static class ExtensionMethods
{
public static int IndexOfSequence<T>(this IEnumerable<T> source, IEnumerable<T> sequence)
{
return source.IndexOfSequence(sequence, EqualityComparer<T>.Default);
}
public static int IndexOfSequence<T>(this IEnumerable<T> source, IEnumerable<T> sequence, IEqualityComparer<T> comparer)
{
var seq = sequence.ToArray();
int p = 0; // current position in source sequence
int i = 0; // current position in searched sequence
var prospects = new List<int>(); // list of prospective matches
foreach (var item in source)
{
// Remove bad prospective matches
prospects.RemoveAll(k => !comparer.Equals(item, seq[p - k]));
// Is it the start of a prospective match ?
if (comparer.Equals(item, seq[0]))
{
prospects.Add(p);
}
// Does current character continues partial match ?
if (comparer.Equals(item, seq[i]))
{
i++;
// Do we have a complete match ?
if (i == seq.Length)
{
// Bingo !
return p - seq.Length + 1;
}
}
else // Mismatch
{
// Do we have prospective matches to fall back to ?
if (prospects.Count > 0)
{
// Yes, use the first one
int k = prospects[0];
i = p - k + 1;
}
else
{
// No, start from beginning of searched sequence
i = 0;
}
}
p++;
}
// No match
return -1;
}
}
I didn't fully test it, so it might still contain bugs. I just did a few tests on well-known corner cases to make sure I wasn't falling into obvious traps. Seems to work fine so far...
I think the complexity is close to O(n), but I'm not an expert of Big O notation so I could be wrong... at least it only enumerates the source sequence once, whithout ever going back, so it should be reasonably efficient.
The code you say you want to be able to use isn't LINQ, so I don't see why it need be implemented with LINQ.
This is essentially the same problem as substring searching (indeed, an enumeration where order is significant is a generalisation of "string").
Since computer science has considered this problem frequently for a long time, so you get to stand on the shoulders of giants.
Some reasonable starting points are:
http://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm
http://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_string_search_algorithm
http://en.wikipedia.org/wiki/Rabin-karp
Even just the pseudocode in the wikipedia articles is enough to port to C# quite easily. Look at the descriptions of performance in different cases and decide which cases are most likely to be encountered by your code.
I understand this is an old question, but I needed this exact method and I wrote it up like so:
public static int ContainsSubsequence<T>(this IEnumerable<T> elements, IEnumerable<T> subSequence) where T: IEquatable<T>
{
return ContainsSubsequence(elements, 0, subSequence);
}
private static int ContainsSubsequence<T>(IEnumerable<T> elements, int index, IEnumerable<T> subSequence) where T: IEquatable<T>
{
// Do we have any elements left?
bool elementsLeft = elements.Any();
// Do we have any of the sub-sequence left?
bool sequenceLeft = subSequence.Any();
// No elements but sub-sequence not fully matched
if (!elementsLeft && sequenceLeft)
return -1; // Nope, didn't match
// No elements of sub-sequence, which means even if there are
// more elements, we matched the sub-sequence fully
if (!sequenceLeft)
return index - subSequence.Count(); // Matched!
// If we didn't reach a terminal condition,
// check the first element of the sub-sequence against the first element
if (subSequence.First().Equals(e.First()))
// Yes, it matched - move onto the next. Consume (skip) one element in each
return ContainsSubsequence(elements.Skip(1), index + 1 subSequence.Skip(1));
else
// No, it didn't match. Try the next element, without consuming an element
// from the sub-sequence
return ContainsSubsequence(elements.Skip(1), index + 1, subSequence);
}
Updated to not just return if the sub-sequence matched, but where it started in the original sequence.
This is an extension method on IEnumerable, fully lazy, terminates early and is far more linq-ified than the currently up-voted answer. Bewarned, however (as #wai-ha-lee points out) it is recursive and creates a lot of enumerators. Use it where applicable (performance/memory). This was fine for my needs, but YMMV.
You can use this library called Sequences to do that (disclaimer: I'm the author).
It has a IndexOfSlice method that does exactly what you need - it's an implementation of the Knuth-Morris-Pratt algorithm.
int startIndex = largeSequence.AsSequence().IndexOfSlice(subSequence);
UPDATE:
Given the clarification of the question my response below isn't as applicable. Leaving it for historical purposes.
You probably want to use mySequence.Where(). Then the key is to optimize the predicate to work well in your environment. This can vary quite a bit depending on your requirements and typical usage patterns.
It is quite possible that what works well for small collections doesn't scale well for much larger collections depending on what type T is.
Of course, if the 90% use is for small collections then optimizing for the outlier large collection seems a bit YAGNI.

A problem with using System.Collections.Specialized.BitVector32: a bug?

I'm trying to do a short simulation where i needed a small bit array, and I chose System.Collections.Specialized.BitVector32.
I'm running it inside a single-threaded object, in a single-threaded loop about 1,000,000 times, each time for indexes {0,1,2}.
Here is the code:
private System.Collections.Specialized.BitVector32 currentCalc
= new System.Collections.Specialized.BitVector32();
private void storeInCurrent(int idx, bool val)
{
currentCalc[idx] = val;
if (currentCalc[idx] != val)
{
throw new Exception("Inconceivable!");
}
}
To my understanding, the exception should not be thrown, but sometimes it does! An exception is not thrown every time, but in a fair percent - a CONSTANT 1/6 of the time! (which is even stranger)
What am I doing wrong?
Look at MSDN; the indexer takes the mask, not the index. So that is:
int mask = 1 << idx;
then use currentCalc[mask]
This is odd though; if you are happy enough to use masks - why would one be using BitVector32, rather than just an int. I also assumed the indexer would take the index. VERY odd design decision.

Categories

Resources