Short circuit variable sequence override - c#

I am working in a C# based program. I am attempting to create a short circuit conditional statement:
if(safety() == 'Yes' && reason() == 'Yes')
{
allowed = true;
}
The way the software is set up, however, the software perpetually views the "reason" variable as the first condition in the if statement, no matter what order I record the variables in. This is causing the 2nd variable to always run, when really, I only need it to run when "safety" == 'Yes'.
This is a long-winded way to ask: Is there any way to override the default sequence of the variables for this one instance in the script?

Related

Is it cost expensive to use "if ( gameobject == null )"? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed last month.
Improve this question
I usually use if ( gameobject == null ) but I heard this is very expensive in game.
I checked if ( gameobject == null ) and if ( boolvalue == false ), but cannot notice any difference.
Could you explain why this check is cost expensive? Thank you in advance.
Generally, questions like this could fall into the "opinion" category, but in this case, we can quantify an answer by running a small test.
There's actually a few things going on here, and there's a deeper issue going on.
I'll start with the test code:
public class Test : MonoBehaviour
{
public GameObject prefab;
private IEnumerator Start ( )
{
var go = Instantiate(prefab);
Destroy(go);
Debug.Log ( $"go is null: {go is null}. go == null: {go == null}." ); // False False.
yield return null; // skip to next frame
Debug.Log ( $"go is null: {go is null}. go == null {go == null}." ); // False True.
yield return null; // skip to next frame
var sw = new Stopwatch();
sw.Start ( );
for ( var i = 0; i < 10_000_000; ++i )
_ = go is null;
sw.Stop ( );
Debug.Log ( $"go is null: {sw.ElapsedMilliseconds} ms" ); // Test machine : ~10 ms
sw.Reset ( );
sw.Start ( );
for ( var i = 0; i < 10_000_000; ++i )
_ = go == null;
sw.Stop ( );
Debug.Log ( $"go == null: {sw.ElapsedMilliseconds} ms" ); // Test machine : ~4000 ms
yield return null; // skip to next frame
Debug.Log ( $"go is null: {go is null}. go == null {go == null}." ); // STILL False True.
#if UNITY_EDITOR
EditorApplication.ExitPlaymode ( );
#endif
}
}
So, the first thing to notice is that after we instantiate and immediately destroy an object, in that particular frame, the object isn't 'destroyed' in either the managed or unmanaged 'memory', as indicated by the "False False".
However, once we skip to the next frame, you'll notice that the unmanaged (Unity backend processing) has marked the object as being null. There's an issue though, the managed code still sees that go referencing an object, which it kind of is, just not a valid backend object anymore. This is why the next debug line will indicate "False True" for the null checks.
The reason I'm bringing this up is because some developers mistakenly think that short-circuiting and bypassing the overloaded '==' operator is fine. It works most of the time, right? Well, clearly it doesn't, as demonstrated here.
So, now to the timing of using '=='. There's a HUGE difference between using object == null and object is null. As you can see, in the order of 400x times slower using '=='. That's because Unity has overloaded the '==' operator to not just check if a reference is null, but also if the underlying backend object is null too. This is a costly process (comparatively), and is why people say to avoid it. BUT, just because something else is faster, does NOT make it any better, and in this case, using the faster check can lead to bugs.
The solution would be to keep track of the managed reference yourself. To do that, you would do:
var go = Instantiate(prefab);
Destroy(go);
go = null;
Debug.Log ( $"go is null: {go is null}. go == null: {go == null}." ); // True True.
If every time you destroy a Unity object you also set the reference to null, you can then safely check the null status of a reference using object is null which is significantly faster that object == null.
Now, having said all of that!
Take note that to get any meaningful millisecond values in the StopWatch, I had to loop through the checks 10 MILLION times! Which then brings me to my final point... there are PLENTY of other places to eke out performance for your game than worrying about whether '==' is expensive or not. Use it, and focus on the rest of your code.
An answer for the check's expensiveness is as follows:
"This transition to native code can be expensive, as Unity will perform lookups and validation to convert the script reference to the native reference. While small, the cost of comparing a Unity object to null is much more expensive than a comparison with a plain C# class, and should be avoided inside a performance critical context, and inside loops."
Despite this answer, I've heard many fellow developers say that the checks aren't very intensive at all, unless if spammed or used en masse. You should only really worry about it if your performance on your project begins to dip.
However, a less-intensive version of the code is as follows:
if (!System.Object.ReferenceEquals(gameObject, null)) {
// do stuff with gameObject
}
Links to both answers and further explanation below:
https://github.com/JetBrains/resharper-unity/wiki/Avoid-null-comparisons-against-UnityEngine.Object-subclasses
https://subscription.packtpub.com/book/game+development/9781785884580/2/ch02lvl1sec23/faster-gameobject-null-reference-checks
There is a custom implementation of == for UnityEngine.Object. Mainly because we don't know for sure when exactly the Garbage Collector will erase the UnityEngine.Object at the c# level after it has been destroyed in the underlying c++ engine level Unity is actually running on.
Regarding performance
If you look into the source code for both ==
public static bool operator==(Object x, Object y) { return CompareBaseObjects(x, y); }
and the implicit bool operator
public static implicit operator bool(Object exists)
{
return !CompareBaseObjects(exists, null);
}
you see that basically both under the hood use the exact same method and finally link into the underlying c++ method. The implicit bool basically equals
return theObject != null;
just written differently ;)
I would boldly claim there shouldn't be any difference in performance at all - but am also happy to be proven wrong ^^ - and I would say it comes more down to preferences. Some people prefer the explicit written down == null for readability, I personally prefer the bool operator.
However
One main issue with that == operator comes more when using the ?. or ?? operators as these work directly on the System.Object level and totally bypass Unity's custom implementations. (See further information e.g. Why does C# null-conditional operator not work with Unity serializable variables?)
This can be a huge pitfall when using != null and the IDE suggesting to rather use ?. and the developer blindly following it!
I don't know Visual Studio nowadays but Rider e.g. explicitly handles UnityEngine.Object different and always suggests to rather use the bool operator instead of == null and also warns about the above mentioned pitfall of bypassing the native null check

C# variable in a function become randomly not available

I'm not really sure if I will be able to explain this behavior but I'll try. I have a program like a dashboard where some graph modules are initialized at startup, each module has a sole purpose to show a graph has a function passed to it which determine the data shown.
The module building (initializing each module type with the corresponding function) is handled in a separate thread using Task. But randomly some of these functions stop working and the List with the data stop being available as if it was never declared.
This is one of the functions, keep in mind it's kind of random which one throws this error, but one of these will always throw an exception. I really can't track down what could cause this behavior I thought about the resources being deleted by other thread but this List is created at startup and only passed and used as a reference. And nowhere in the program I ever reset this list. The same code work in other project and while debugging step by step... I'm really out of tracks to follow
private static IEnumerable<ICompositeValue> GroupEvent(IEnumerable<Event> events, DateTime referenceDate, Month month)
{
List<ICompositeValue> Values= new List<ICompositeValue>();
foreach (Days day in (Giorni[])Enum.GetValues(typeof(Days)))
{
if (day != Giorni.Sunday)
if (events== null) return null; //this was tried to catch the exception
Values.Add(new ICompositeValue()
{
Argument = day.ToString(),
Valore = event.Count(x => (int)x.DDB_APDATA.Value.DayOfWeek == (int)day && (int)x.DDB_APDATA.Value.Month == (int)month && x.DDB_APDATA.Value.Year == referenceDate.Year)
}); ;
}
return valori;
}
As shown in this image Visual Studio can't even evaluate the List value as if it was never declared
Can someone point me in the right direction?
Thanks to everyone!
I just wanted to thank those who tried to help me.
I still didn't get why the debugger acted the way it did since it showed me "x" was null not the inside property, but I managed to track down the problem. I noticed the object mapping from the DataTable was acting strange with the DateTime type variable and indeed something returned null from time to time
As Jeroen Mostert has suggested it seems like some property in your lambda is unexpectedly null. The reason events is not available is because your debugger context is inside the lambda.
x => (int)x.DDB_APDATA.Value.DayOfWeek == (int)day && (int)x.DDB_APDATA.Value.Month == (int)month && x.DDB_APDATA.Value.Year == referenceDate.Year
So one of either x, DDB_APDATA, or Value will likely be null.

Property Initialization and Comparison Timing

Context: C#, WPF, MVVM
In my viewmodels I have been using initialization logic for some of my properties that is basically a check to see if the backing property is null and, if so, initialize it. Finally, return the backing property. Here's an example for list that allows a user to select items to filter by:
List<CBPicklistString> _clientClassificationFilterList;
public List<CBPicklistString> ClientClassificationFilterList
{
get
{
Debug.WriteLine("ClientClassificationFilterList - Get: " + _clientClassificationFilterList?.Count ?? "Null");
if (_clientClassificationFilterList == null)
{
_clientClassificationFilterList = CBPicklists.PicklistStrings(CBPicklists.CLIENT_CLASSIFICATIONS).ToList();
_clientClassificationFilterList.Insert(0, new CBPicklistString() { PicklistStringId = 0, PicklistStringValue = "(All Client Classes)" });
SelectedClientClassificationFilter = _effectiveClientClassificationFilter = _clientClassificationFilterList[0];
OnPropertyChanged("SelectedClientClassificationFilter");
}
return _clientClassificationFilterList;
}
}
My method to apply the filter logic has this code:
if (_effectiveClientClassificationFilter != ClientClassificationFilterList[0])
ActiveClientFilters.Add(new ActiveFilter(_effectiveClientClassificationFilter.PicklistStringValue, "ClientClassification"));
On the initial run, the getter should initialize the list and _effectiveClientClassificationFilter and the if statement should see the comparison as false (objects are equal), meaning that there is no active filter to set. But what I am seeing is that the if statement is behaving as if it sees a true (objects are not equal). When I check the values in the debugger, they are, in fact, equal. It's acting as if there is a concurrency issue where the initialization isn't finishing prior to the comparison. But this isn't a multi-threaded bit of code. Is .Net (or WPF) doing its own thing, here? Is this not a valid way to approach the list initialization? I use this logic paradigm all over the place, (and have been, for years) but this is the first time and the only place I am seeing this funky behavior. There's not a lot of other related code involved.
What am I missing?
I am not sure, but i think the initial value of _effectiveClientClassificationFilter being first in the comparison is used and then the ClientClassificationFilterList is calculated changing the value of _effectiveClientClassificationFilter which i suppose it does not know. So if you reverse the order of condition, it will work correctly.
Instead of
if (_effectiveClientClassificationFilter != ClientClassificationFilterList[0])
use
if (ClientClassificationFilterList[0] != _effectiveClientClassificationFilter)

Memory in if condition

Ok, this is a hard question for me to ask, to make you udnerstand what I want to know
So assume this pseudo code :
While(true)
if(boolean is true)
else
End While
Ok, with this, I have a while who,s always running, what I wonder is if there's anyway to enter the if without re valuating the boolean each time, also you need to know the boolean may change but never in the if itself.
I know it seems crazy thinking, I just wonder if it's possible to enter a condition without evaluating it, IF the condition was true the time before.
EDIT
Also I'm imaginating this idea from an electric cicuit, imagine a switch if the contact is made the electricity will go straith to the light else it woN't pass but it doN,t really check wich way it just assume where he can go, I know I,m really confusing :S
EDIT 2
Maybe this will be more clear ? i'm not sure
No, because what you're asking for is "how do I branch without checking a condition?" and the answer is, you can't.
If the condition check is a complex operation then You can memorize the result of a condition check in a boolean variable, and branch on the variable.
However, in order to truely eliminate the branch in your example, the general pattern is to separate the true and false conditions to be outside the while loop:
while(true)
{
if(condition) break;
}
while(true)
{
// condition was true
}
Simple, just simply emit the if statement if you want it to pass its condition automatically.

how to achieve the project requirement

I have a method Modify() shown below
// Convert SortedList of objects
if (retval) //
{
// Release the database lock
Debug.Verbose(func, "Unloc");
The functionality which i want to achieve is if flag RuntimeUp true and m_reconnectInProgress false that means if(RuntimeUp && !m_reconnectInProgress) i have to do the entire procees in the Modify() method otherwise i need to return 'retval' as false .We will get retval from ClientModify(col) method also which is processed by some other side
If i put check if(RuntimeUp && !m_reconnectInProgress) on the very begginning and down side
else part returning retval = false is sufficient or is there any other convenient way to do that so that we can avoid bad logic
I did above assumption based on this comment obtained"" There is no need to create the list of modified objects[col.Add(dmo);] if the RuntimeUp == false and m_reconnectInProgress ==true. You can just return false at the top of the Modify method that means You can perform these checks at the beginning of the Modify method rather than waiting until the call to ClientModify ""
If I understand correctly I'd just add the lines
if(!RuntimeUp || m_reconnectInProgress)
return false;
At the very top of the method, which I think is a perfectly acceptable way of avoiding running the method if the application isn't in the correct state for running it right then.
However, the comment bit of your question does not mention that it should check for reconnect in progress, so I'm not sure if you should be doing that?

Categories