Partial short circuit boolean evaluation in Javascript or C# - c#

Is there a way, in JavaScript or C#, to determine the outcome of a logical expression before the
values of all variables have been retrieved?
Or to put it differently; can an expression be evaluated such that it returns either 'true', 'false', or 'maybe'? Wherein 'maybe' indicates that more data is needed.
To explain: I have a process in which it takes some time to retrieve data from the database backend and I would like to see if we can skip retrieving certain data if not necessary. But the logical expressions have been predetermined and can not be changed or taken apart.
For instance, consider the following expression:
((a = 1) and (b = 2)) or (c = 3)
There are several possibilities:
If a and b have been retrieved but c has not yet been retrieved:
If a=1 and b=2 then the expression will always return true and I can skip retrieving the value for c
If a=0 and b=2 then the first part will be false, and I need to retrieve the value for c in order to being able to determine the outcome
If c has been retrieved, but and a and b have not yet been retrieved.
If c=3 then the expression will always return true and I can skip retrieving the value for a and b.
If c=2 then the first part will be false, and I need to retrieve the value for a and b in order to being able to determine the outcome
In these situations, just knowing that an outcome is already determined, or that more data is needed can significantly speed up a process.
Does anybody have an idea? A process, function, algorithm?

So to cover your very specific code, you can simply use the following:
if(CHasValue())
return (c == 3) or ((a == 1) and (b == 2))
else
return ((a == 1) and (b == 2)) or (c == 3)
short circuiting of operators will take care of the rest.
This doesn't scale very well with more complex expressions though. In order to really cover any arbitrary boolean expression you really need to create your own new type, and corresponding boolean operators.
We'll start out with an interface defining a boolean value that may or may not have computed its value yet:
public interface IComputableBoolean
{
public bool Value { get; }
public bool ValueComputed { get; }
}
The first implementation is the easy one; it's a computable boolean representing a value that we already know:
public class ComputedBoolean : IComputableBoolean
{
public ComputedBoolean(bool value)
{
Value = value;
}
public bool Value { get; private set; }
public bool ValueComputed { get { return true; } }
}
Then there's the slightly more complex case, the boolean value that is generated based on a function (presumably something that is potentially long running, or that has side effects). It will take a delegate that computes the expression, evaluate it the first time the value is requested, and return a cached value (and indicate that it has computed its value) from then on.
public class DeferredBoolean : IComputableBoolean
{
private Func<bool> generator;
private bool? value = null;
public DeferredBoolean(Func<bool> generator)
{
this.generator = generator;
}
public bool Value
{
get
{
if (value != null)
return value.Value;
else
{
value = generator();
return value.Value;
}
}
}
public bool ValueComputed { get { return value != null; } }
}
Now we just need to create And, Or, and Not methods that apply to this interface. They should first check to see if enough values are computed to allow it to short circuit, and if not, they should create a deferred boolean representing the computation of the value. This propagation of deferred values is important, because it allows complex boolean expressions to be composed and still properly short circuit with the minimal amount of needed computation.
public static IComputableBoolean And(
this IComputableBoolean first,
IComputableBoolean second)
{
if (first.ValueComputed && !first.Value ||
second.ValueComputed && !second.Value)
return new ComputedBoolean(false);
else
return new DeferredBoolean(() => first.Value && second.Value);
}
public static IComputableBoolean Or(
this IComputableBoolean first,
IComputableBoolean second)
{
if (first.ValueComputed && first.Value ||
second.ValueComputed && second.Value)
return new ComputedBoolean(true);
else
return new DeferredBoolean(() => first.Value && second.Value);
}
The Not operation is a bit different in that it can't short circuit at all, but it's still important to have in that it continues to defer evaluation of the given boolean expression, because it may end up not being needed.
public static IComputableBoolean Not(
this IComputableBoolean boolean)
{
if (boolean.ValueComputed)
return new ComputedBoolean(boolean.Value);
else
return new DeferredBoolean(() => boolean.Value);
}
We can now represent the expression that you have like so (using actual long running operations to compute a, b, and/or c as needed):
var a = new DeferredBoolean(() => false);
var b = new DeferredBoolean(() => true);
var c = new DeferredBoolean(() => false);
var expression = a.And(b).Or(c);
bool result = expression.Value;

Assuming a, b, c are truthy once they are loaded, and falsy beforehand (or perhaps a,b,c contain a "loaded" property you could check):
var isValid = false;
if (a && b) {
if (a == 1 && b == 2) {
isValid = true;
}
}
if (!isValid && c) {
if (c == 3) {
isValid = true;
}
}

Related

Check if value exists. Equals(...) vs. patternMatching

I want to check if a given object value is null or is an empty string. I got the following ideas:
...
public void Cmp1(object a) {
if(a == null || Equals(a, string.Empty)) {
Value = null;
return;
}
....
}
public void Cmp2(object a) {
if(a == null || (a is string stringValue && string.IsNullOrEmpty(stringValue))) {
Value = null;
return;
}
....
}
Which one is better? Is Equals exposing some danger? Or (a is string stringValue && string.IsNullOrEmpty(stringValue)) is super slow?
The problem with the second option is you almost certainly want to use stringValue after the conditional block, meaning you must do the work a second time.
I might use the as operator, like this:
public void Cmp(object a)
{
var stringValue = a as string;
if (string.IsNullOrEmpty(stringValue)) {
Value = null; //this suggests the function should return something, instead of a void method
return;
}
// ...
}
Or I might negate the condition (and remove the null check):
public void Cmp(object a) {
// pattern matching is still safe to use if `a` is null
if(a is string stringValue && !string.IsNullOrEmpty(stringValue)) {
// stringValue is in scope here
}
else {
// but not here... but we no longer need it
Value = null;
}
}
If you don't intend to use stringValue again at all, I'd write it like this:
public void Cmp(object a)
{
if (!(a is string) || string.IsNullOrEmpty((string) a)) {
Value = null;
return;
}
// ...
}
But most of all... none of this is likely to drive the performance of your program. You're spending a bunch of time worrying about details that would be much better spent looking at profiler results, which can tell you exactly where to spend your time optimizing to make your app faster.

C# Dictionary throws KeyNotFoundException when key exists

I am storing a 2D array that represents a distance matrix between vectors as a Dictionary<DistanceCell, double>. My implementation of DistanceCell has two string fields representing the vectors being compared.
class DistanceCell
{
public string Group1 { get; private set; }
public string Group2 { get; private set; }
public DistanceCell(string group1, string group2)
{
if (group1 == null)
{
throw new ArgumentNullException("group1");
}
if (group2 == null)
{
throw new ArgumentNullException("group2");
}
this.Group1 = group1;
this.Group2 = group2;
}
}
Since I'm using this class as a key, I overrode Equals() and GetHashCode():
public override bool Equals(object obj)
{
// False if the object is null
if (obj == null)
{
return false;
}
// Try casting to a DistanceCell. If it fails, return false;
DistanceCell cell = obj as DistanceCell;
if (cell == null)
{
return false;
}
return (this.Group1 == cell.Group1 && this.Group2 == cell.Group2)
|| (this.Group1 == cell.Group2 && this.Group2 == cell.Group1);
}
public bool Equals(DistanceCell cell)
{
if (cell == null)
{
return false;
}
return (this.Group1 == cell.Group1 && this.Group2 == cell.Group2)
|| (this.Group1 == cell.Group2 && this.Group2 == cell.Group1);
}
public static bool operator ==(DistanceCell a, DistanceCell b)
{
// If both are null, or both are same instance, return true.
if (System.Object.ReferenceEquals(a, b))
{
return true;
}
// If either is null, return false.
// Cast a and b to objects to check for null to avoid calling this operator method
// and causing an infinite loop.
if ((object)a == null || (object)b == null)
{
return false;
}
return (a.Group1 == b.Group1 && a.Group2 == b.Group2)
|| (a.Group1 == b.Group2 && a.Group2 == b.Group1);
}
public static bool operator !=(DistanceCell a, DistanceCell b)
{
return !(a == b);
}
public override int GetHashCode()
{
int hash;
unchecked
{
hash = Group1.GetHashCode() * Group2.GetHashCode();
}
return hash;
}
As you can see, one of the requirements of DistanceCell is that Group1 and Group2 are interchangeable. So for two strings x and y, DistanceCell("x", "y") must equal DistanceCell("y", "x"). This is why I implemented GetHashCode() with multiplication because DistanceCell("x", "y").GetHashCode() must equal DistanceCell("y", "x").GetHashCode().
The problem that I'm having is that it works correctly roughly 90% of the time, but it throws a KeyNotFoundException or a NullReferenceException the remainder of the time. The former is thrown when getting a key from the dictionary, and the latter when I iterate over the dictionary with a foreach loop and it retrieves a key that is null that it then tries to call Equals() on. I suspect this has something to do with an error in my GetHashCode() implementation, but I'm not positive. Also note that there should never be a case where the key wouldn't exist in the dictionary when I check it because of the nature of my algorithm. The algorithm takes the same path every execution.
Update
I just wanted to update everyone that the problem is fixed. It turns out that it had nothing to do with my Equals() or GetHashCode() implementation. I did some extensive debugging and found that the reason I was getting a KeyNotFoundException was because the key didn't exist in the dictionary in the first place, which was strange because I was positive that it was being added. The problem was that I was adding the keys to the dictionary with multiple threads, and according to this, the c# Dictionary class isn't thread-safe. So the timing must have been perfect that an Add() failed and thus the key was never added to the dictionary. I believe this can also explain how the foreach loop was bringing up a null key on occasion. The Add()'s from multiple threads must have messed up some internal structures in the dictionary and introduced a null key.
Thanks to every one for your help! I'm sorry that it ended up being a fault entirely on my end.
Take a look at this blog post by Eric Lippert
It says that the result of GetHashCode should never change even if you change the content of the object. The reason is that Dictionary is using buckets for faster indexing. Once you change the GetHasCode result, the Dictionary will not be able to find the right bucket for your object and this can lead to "Key not found"
I might be wrong, but it is worth testing.
I believe what is missing for you is this answer
Using an object as a generic Dictionary key
You probably not stating you implement IEquatable interface
To me your code looks correct. (It can possibly be (micro-)optimized, but it looks as if it will be correct in all cases.) Can you provide some code where you create and use the Dictionary<DistanceCell, double>, and things go bad? The problem may lie in code you haven't shown us.

c#: Not finding object in list

I am using LINQ .Find() and it's not stopping when it finds a match. I have:
List<ipFound> ipList = new List<ipFound>();
ipFound ipTemp = ipList.Find(x => x.ipAddress == srcIP);
if (ipTemp == null) {
// this is always null
}
public class ipFound
{
public System.Net.IPAddress ipAddress;
public int bytesSent;
public int bytesReceived;
public int bytesTotal;
}
Any ideas? I'm going nuts over here.
Thanks!
You need to use .Equals instead of ==.
var a = IPAddress.Parse("1.2.3.4");
var b = IPAddress.Parse("1.2.3.4");
Console.WriteLine(a == b); // False
Console.WriteLine(a.Equals(b)); // True
In the sample above, a == b is False because those are two different objects. However, a.Equals(b) is True because they have equal values.
Use IPAddress.Equals instead of comparing references (==):
ipFound ipTemp = ipList.Find(x => x.ipAddress.Equals(srcIP));
As a side note, usually class names are PascalCased (IPFound vs. ipFound)
Example: http://ideone.com/lAeiMm

Avoiding calls to mscorlib when comparing strings?

Is there a possible way that let me compare strings without calling the op_Equality function is mscorlib?
For example:
string s1 = "hi";
if(s1 == "bye")
{
Console.Writeline("foo");
}
Compiles to:
IL_0003: call bool [mscorlib]System.String::op_Equality(string, string)
And looking at op_Equality at mscorlib from GAC it calls another method Equals(string, string)
Code:
public static bool Equals(string a, string b)
{
return a == b || (a != null && b != null && string.EqualsHelper(a, b));
}
it uses the op code bne.une.s to compare those strings.
Now back at my question, how can I compare 2 strings without calling any function from the mscorlib like the method Equals does.
Now back at my question, how can I compare 2 strings without calling any function from the mscorlib like the method Equals does.
You can't - at least not without writing your own string comparison method from scratch.
At some point, you'd have to at least call String.Equals(a,b) (in order to have the private EqualsHelper method called, which does the actual comparison), which is also defined in mscorlib.
You could call Equals directly if you wish to avoid the operator call, though:
string s1 = "hi";
if (string.Equals(s1, "bye"))
{
Console.WriteLine("foo");
}
This would avoid the call to op_Equality, bypassing it and calling Equals directly.
That being said, there is really no reason to avoid calling op_Equality on strings in the first place...
It seems like you are asking for a string comparison function. Strings are basically arrays of characters that you can index in a similar fashion. Here is a simple string comparison algorithm.
public static bool Equals(string left, string right)
{
if (ReferenceEquals(left, null)) return ReferenceEquals(right, null);
if (left.Length != right.Length) return false;
for (int i = 0; i < left.Length; i++)
{
if (left[i] != right[i])
return false;
}
return true;
}
Having shown you that, there is no reason to avoid the mscorlib implementation, since my example makes several calls to mscorlib.
This is another way to compare:
string s1 = "Hello";
bool same = s1.CompareTo("Hello") == 0;
bool different = s1.CompareTo("GoodBye") != 0;
Console.WriteLine(same);
Console.WriteLine(different);
In this case, both should report "True" to the console.
Another way:
private static bool CheckEqual(string s1, string s2)
{
char[] c1 = (s1 == null) ? new char[0] : s1.ToCharArray();
char[] c2 = (s2 == null) ? new char[0] : s2.ToCharArray();
if (c1.Length != c2.Length) { return false; }
for (int i = 0; i < c1.Length; i++)
{
if (!c1[i].Equals(c2[i])) { return false; }
}
return true;
}
Given that the String class is provided by mscorlib, there is absolutely no way to compare two strings without using mscorlib. Even just using the indexer to get each character calls into mscorlib.
The only way to avoid mscorlib is to not use the .Net runtime, but that's pretty difficult if you want to use C#.

Why do 2 delegate instances return the same hashcode?

Take the following:
var x = new Action(() => { Console.Write("") ; });
var y = new Action(() => { });
var a = x.GetHashCode();
var b = y.GetHashCode();
Console.WriteLine(a == b);
Console.WriteLine(x == y);
This will print:
True
False
Why is the hashcode the same?
It is kinda surprising, and will make using delegates in a Dictionary as slow as a List (aka O(n) for lookups).
Update:
The question is why. IOW who made such a (silly) decision?
A better hashcode implementation would have been:
return Method ^ Target == null ? 0 : Target.GetHashcode();
// where Method is IntPtr
Easy! Since here is the implementation of the GetHashCode (sitting on the base class Delegate):
public override int GetHashCode()
{
return base.GetType().GetHashCode();
}
(sitting on the base class MulticastDelegate which will call above):
public sealed override int GetHashCode()
{
if (this.IsUnmanagedFunctionPtr())
{
return ValueType.GetHashCodeOfPtr(base._methodPtr);
}
object[] objArray = this._invocationList as object[];
if (objArray == null)
{
return base.GetHashCode();
}
int num = 0;
for (int i = 0; i < ((int) this._invocationCount); i++)
{
num = (num * 0x21) + objArray[i].GetHashCode();
}
return num;
}
Using tools such as Reflector, we can see the code and it seems like the default implementation is as strange as we see above.
The type value here will be Action. Hence the result above is correct.
UPDATE
My first attempt of a better implementation:
public class DelegateEqualityComparer:IEqualityComparer<Delegate>
{
public bool Equals(Delegate del1,Delegate del2)
{
return (del1 != null) && del1.Equals(del2);
}
public int GetHashCode(Delegate obj)
{
if(obj==null)
return 0;
int result = obj.Method.GetHashCode() ^ obj.GetType().GetHashCode();
if(obj.Target != null)
result ^= RuntimeHelpers.GetHashCode(obj);
return result;
}
}
The quality of this should be good for single cast delegates, but not so much for multicast delegates (If I recall correctly Target/Method return the values of the last element delegate).
But I'm not really sure if it fulfills the contract in all corner cases.
Hmm it looks like quality requires referential equality of the targets.
This smells like some of the cases mentioned in this thread, maybe it will give you some pointers on this behaviour. else, you could log it there :-)
What's the strangest corner case you've seen in C# or .NET?
Rgds GJ
From MSDN :
The default implementation of
GetHashCode does not guarantee
uniqueness or consistency; therefore,
it must not be used as a unique object
identifier for hashing purposes.
Derived classes must override
GetHashCode with an implementation
that returns a unique hash code. For
best results, the hash code must be
based on the value of an instance
field or property, instead of a static
field or property.
So if you have not overwritten the GetHashCode method, it may return the same. I suspect this is because it generates it from the definition, not the instance.

Categories

Resources