I am getting an "Expensive Method Invocation" AND a "Null comparison expensive" warnings and I would like to know how to fix these.
void Update()
{
CheckCollision();
}
and in CheckCollison where the errors are happening, shown in comments below,.
void CheckCollision()
{
var topHit = Physics2D.OverlapCircle(topCollision.position, 0.2f, playerLayer);
if (topHit != null) // ***<<<< NULL COMPARISON EXPENIVE!***
{
if (topHit.gameObject.CompareTag("Player"))
{
if (!stunned)
{
var rigidBodyTopHit = topHit.gameObject
.GetComponent<Rigidbody2D>(); // ***<<<< EXPENSIVE METHOD INVOCATION!***
rigidBodyTopHit.velocity = new Vector2(rigidBodyTopHit.velocity.x, 7f);
canMove = false;
_myBody.velocity = new Vector2(0,0);
_animator.Play("SnailStunned");
stunned = true;
}
}
}
if (!Physics2D.Raycast(downCollision.position, Vector2.down, 0.1f))
{
ChangeDirection();
}
}
These are not warnings, but informational highlights. They are intended to inform you that you are doing something that is known to be expensive, inside a performance sensitive context (the Update method) and you can re-evaluate your approach if necessary.
The "if necessary" bit is important - only you can decide if the performance characteristics of this Update method are appropriate for your game/application. If this happens in a single game object in an options screen that's rarely used, then it's most likely not a problem. But if it's in an object that is instantiated many times and used in core gameplay, maybe these expensive methods will add up and reduce performance (or affect battery life).
Generally speaking, it's probably going to be very hard (and unnecessary) to write code that does not have any of these informational highlights, but if you find that you have a lot of code that has a lot of highlights, then it's a good indication that you should profile and see if you're happy with the results.
You can find out more about these highlights by using Alt+Enter, expanding the inspection options item and selecting the "Why is Rider/ReSharper suggesting this?" item. This will open a web page with more details about that particular highlight.
This page also has an overview and more details, and the inspections can also be disabled in the Preferences | Editor | Inspection Settings | Inspection Severity | C# settings page (under Unity | Performance indicators).
Looking at the items marked in the code sample, the equality comparison is expensive because it also checks to see if the underlying engine object has been destroyed, which means a transition into native code. If you know that the object hasn't been destroyed (and seeing that it's returned from a Unity API, I think that's a safe bet), then you can replace it with:
if (!Object.ReferenceEquals(topHit, null)) {
// …
}
But remember that this is a micro-optimisation that is potentially unnecessary, in your use case.
(Calling the implicit bool operator with if (!topHit) is exactly the same as if (topHit != null), both operators call the private Object.CompareBaseObjects method)
The second item is a call to GetComponent, which is known to be expensive, but is necessary in this context. That's ok - this is just informational, not telling you that you've done something wrong.
Related
I wonder if someone can clarify when to await and when not to. Consider this code
public Task<List<User>> GetUsersForParent(int someParentId)
{
var qry = Context.Users.Where(u=>u.parent = someParentId)
.OrderBy(u=>u.Surname)
return FilterActive(qry);
}
//Actually in a generic base class, but not important (I don't think)
protected Task<List<T>> FilterActive(IQueryable<T> query) where T: BaseEntity
{
return query.Where( q=>q.Active == true ).ToListAsync();
}
Then it is used like this
var users = await DbHandler.GetUsersForParent(1);
So the calling method is awaited, but the others are not. Is this correct?
Should the method calling the ToListAsync() be awaited? (this I assume is now doing the work)
My reason for this is I am getting the DbContext is being used by a second thread dreaded exception. I am running out of places to look. My understanding is the methods are building up the whole task which is executed, but could this be messing with the dbContext?
Edit re DbContext error
Having narrowed down the potential locations for the issue, via Debug.Print and SQL Query profiling (just in case that helps anyone else) I can see one statement being profiled (the next in profile is logging the exception) and I can see two methods being run via the debug print.
One of these methods is a PermissionsManager which, when constructed, initialises itself and loads the user data. This is constructed when requested via the DI framework.
The other method is the single query on the OnGet() method for the page. It is running a single query to get an entity by ID, it is awaited correctly.
My working theory at the moment is that the Thread running the DI construction and another thread running the Page initialise are colliding.
When I made the PermissionManager just _person = new Person() // await db.users.get(userid) the issue goes away. I could replicate the issue 1 in 2 or 3 times of refresh, and with that commented I could not replicate, despite refreshing the page 30+ times.
So my real question with async / await is probably more about DI injection and is that construction running on a different thread? if so, any best practice to avoid?
So the calling method is awaited, but the others are not. Is this correct?
I generally recommend using the async and await keywords, and only return the tasks directly if the method is extremely simple.
My reason for this is I am getting the DbContext is being used by a second thread dreaded exception. I am running out of places to look. My understanding is the methods are building up the whole task which is executed, but could this be messing with the dbContext?
No. At least, the code you posted cannot cause that exception. Whether the async/await keywords are used, or whether the tasks are returned directly, the methods are asynchronous and they do not attempt to do more than one thing on the dbcontext at once.
It's possible that your problem is further up the stack. Task.WhenAll is a good thing to search for when tracking this down.
Should the method calling the ToListAsync() be awaited? (this I assume is now doing the work)
If you await the contents of either method you will be returning the result type, not Task of result type which means the execution cannot be deferred.
Your error will be coming up because you either have multiple threads interacting with the same instance of DbContext, awaited or no this would cause problems, that or you have some code calling the ToListAsync()-containing method, or another async DbContext operation without awaiting.
Writing an EF data access layer returning Task is fairly dangerous which can shoot you in the foot very easily.
Given your code structure I would recommend a couple small changes:
public async Task<List<User>> GetUsersForParent(int someParentId)
{
var qry = Context.Users.Where(u=>u.parent = someParentId)
.OrderBy(u=>u.Surname);
qry = FilterActive(qry);
return await qry.ToListAsync();
}
protected IQueryable<T> FilterActive(IQueryable<T> query) where T: BaseEntity
{
return query.Where( q=> q.Active == true );
}
Notably here I would avoid returning Task to reduce risks of improper use and potentially intermittent bugs. The base-class method for FilterActive can return IQueryable<T> to apply the filter without triggering the execution of the operation. This way FilterActive can be applied whether you want a List, a Count, or simply do an Exists check.
Overall I would recommend exploring patterns that return IQueryable<TEntity> rather than List<TEntity> etc. as the later results in either a lot of limitations for performance and flexibility, or requires a lot of boiler-plate code to handle things like:
Sorting,
Pagination,
Getting just a Count,
Performing an Exists check,
Configurable filtering,
Selectively eager loading related data, or
Projection to generate efficient queries
Doing this with methods that return List<TEntity> either results in very complex code to support some of the above considerations, has these operations applied post-execution leading to heavier queries than would otherwise be needed, or requires a lot of near-duplicate code to handle each scenario.
So the constructor thing was a red herring. It was a missing await after all, just not where expected and in code that was unchanged.
I tracked down the culprit. There was a method in the basePage which hooked into the Filter of MVC pages. It took the user and loaded their permissions, however, since this loading of user permissions was made async, this method did not get awaited (it didn't need it before as was synchronous). I moved it to one of the async events on the page life cycle and all seems happy now (with a suitable await!). So it was a missing await, but the moral of the story is any time you make a sync method async, check what the heck is actually using it!
Dart explicitly makes a distinction between Error, that signals a problem in your code's logic and should never happen and should never be caught and Exceptions that signal a problem based on run-time data.
I really like this distinction but I wonder when should I then use assert() functions?
Asserts are ways to perform code useful in development only, without hindering the performances of release mode – usually to prevent bad states caused by a missing feature in the type system.
For example, only asserts can be used to do defensive programming and offer a const constructor.
We can do:
class Foo {
const Foo(): assert(false);
}
but can't do:
class Foo {
const Foo() { throw 42; }
}
Similarly, some sanity checks are relatively expensive.
In the context of Flutter, for example, you may want to traverse the widget tree to check something on the ancestors of a widget. But that's costly, for something only useful to a developer.
Doing that check inside an assert allows both performance in release, and utility in development.
assert(someVeryExpensiveCheck());
Background
In Dart an Exception is for an expected bad state that may happen at runtime. Because these exceptions are expected, you should catch them and handle them appropriately.
An Error, on the other hand, is for developers who are using your code. You throw an Error to let them know that they are using your code wrong. As the developer using an API, you shouldn't catch errors. You should let them crash your app. Let the crash be a message to you that you need to go find out what you're doing wrong.
An assert is similar to an Error in that it is for reporting bad states that should never happen. The difference is that asserts are only checked in debug mode. They are completely ignored in production mode.
Read more on the difference between Exception and Error here.
Next, here are a few examples to see how each is used in the Flutter source code.
Example of throwing an Exception
This comes from platform_channel.dart in the Flutter repo:
#optionalTypeArgs
Future<T?> _invokeMethod<T>(String method, { required bool missingOk, dynamic arguments }) async {
assert(method != null);
final ByteData? result = await binaryMessenger.send(
name,
codec.encodeMethodCall(MethodCall(method, arguments)),
);
if (result == null) {
if (missingOk) {
return null;
}
throw MissingPluginException('No implementation found for method $method on channel $name');
}
return codec.decodeEnvelope(result) as T;
}
The MissingPluginException here is a planned bad state that might occur. If it happens, users of the platform channel API need to be ready to handle that.
Example of throwing an Error
This comes from artifacts.dart in the flutter_tools repo.
TargetPlatform _currentHostPlatform(Platform platform) {
if (platform.isMacOS) {
return TargetPlatform.darwin_x64;
}
if (platform.isLinux) {
return TargetPlatform.linux_x64;
}
if (platform.isWindows) {
return TargetPlatform.windows_x64;
}
throw UnimplementedError('Host OS not supported.');
}
First every possibility is exhausted and then the error is thrown. This should be theoretically impossible. But if it is thrown, then it is either a sign to the API user that you're using it wrong, or a sign to the API maintainer that they need to handle another case.
Example of using asserts
This comes from overlay.dart in the Flutter repo:
OverlayEntry({
required this.builder,
bool opaque = false,
bool maintainState = false,
}) : assert(builder != null),
assert(opaque != null),
assert(maintainState != null),
_opaque = opaque,
_maintainState = maintainState;
The pattern in the Flutter source code is to use asserts liberally in the initializer list in constructors. They are far more common than Errors.
Summary
As I read the Flutter source code, use asserts as preliminary checks in the constructor initializer list and throw errors as a last resort check in the body of methods. Of course this isn't a hard and fast rule as far as I can see, but it seems to fit the pattern I've seen so far.
As asserts are ignored in production mode, you should use them as way to do initial tests to your code logic in debug mode:
In production code, assertions are ignored, and the arguments to assert aren’t evaluated.
When exactly do assertions work? That depends on the tools and framework you’re using:
Flutter enables assertions in debug mode.
Development-only tools such as dartdevc typically enable assertions by default.
Some tools, such as dart and dart2js, support assertions through a command-line flag: --enable-asserts.
In production code, assertions are ignored, and the arguments to assert aren’t evaluated.
Refer:https://dart.dev/guides/language/language-tour#assert
I have some code in a class that takes FileSystemWatcher events and flattens them into an event in my domain:
(Please note, the *AsObservable methods are extensions from elsewhere in my project, they do what they say 🙂.)
watcher = new FileSystemWatcher(ConfigurationFilePath);
ChangeObservable = Observable
.Merge(
watcher.ChangedAsObservable().Select((args) =>
{
return new ConfigurationChangedArgs
{
Type = ConfigurationChangeType.Edited,
};
}),
watcher.DeletedAsObservable().Select((args) =>
{
return new ConfigurationChangedArgs
{
Type = ConfigurationChangeType.Deleted,
};
}),
watcher.RenamedAsObservable().Select((args) =>
{
return new ConfigurationChangedArgs
{
Type = ConfigurationChangeType.Renamed,
};
})
);
ChangeObservable.Subscribe((args) =>
{
Changed.Invoke(this, args);
});
Something that I'm trying to wrap my head around as I'm learning are best practices around naming, ownership and cleanup of the IObservable and IDisposable returned by code like this.
So, some specific questions:
Is it okay to leak IObservables from a class that creates them? For example, is the property I'm assigning this chain to okay to be public?
Does the property name ChangeObservable align with what most people would consider best practice when using the .net reactive extensions?
Do I need to call Dispose on any of my subscriptions to this chain, or is it safe enough to leave everything up to garbage collection when the containing class goes out of scope? Keep in mind, I'm observing events from watcher, so there's some shared lifecycle there.
Is it okay to take an observable and wire them into an event on my own class (Changed in the example above), or is the idea to stay out of the native .net event system and leak my IObservable?
Other tips and advice always appreciated! 😀
Is it okay to leak IObservables from a class that creates them? For
example, is the property I'm assigning this chain to okay to be
public?
Yes.
Does the property name ChangeObservable align with what most
people would consider best practice when using the .net reactive
extensions?
Subjective question. Maybe FileChanges? The fact that it's an observable is clear from the type.
Do I need to call Dispose on any of my subscriptions to
this chain, or is it safe enough to leave everything up to garbage
collection when the containing class goes out of scope?
The ChangeObservable.Subscribe at the end could live forever, preventing the object from being garbage collected if the event is subscribed to, though that could also be your intention. Operator subscriptions are generally fine. I can't see the code for your ChangedAsObservable like functions. If they don't include a Subscribe or an event subscription, they're probably fine as well.
Keep in mind,
I'm observing events from watcher, so there's some shared lifecycle
there.
Since FileWatcher implements IDisposable, you should probably use Observable.Using around it so you can combine the lifecycles.
Is it okay to take an observable and wire them into an event on
my own class (Changed in the example above), or is the idea to stay
out of the native .net event system and leak my IObservable?
I would prefer to stay in Rx. The problem with event subscriptions is that they generally live forever. You lose the ability to control subscription lifecycle. They're also feel so much more primitive. But again, that's a bit subjective.
I'm currently working on a basic AI for enemies in my space shooter project.
In my EnemyAI script, I've a public Transform target that I set when I instantiate a enemy. In the Update loop, I'm looking at the target, then moving using transform.towards and everything works fine. The problem is, the target can die, so I need to check if it is not null before doing all that. Problem is : apparently doing a simple if(target == null) is really bad performance wise, and I need to do it in Update. What should be the best approach to achieve that without having performance problems (let say I want 500 enemies at once). Should I still do it every X frame, cache the position of the target till the next check and move toward that cached result ? That could work but it would introduce jitter if the time between two check if too long.
I couldn't find any "easy" way but I hope there is one, it looks like something really simple and it's causing a lot of troubles :/
Null checks are not that expensive.
Coroutines can help spread the load over multiple frames. But carefully read about their memory usage / garbage collection problems.
You could speed that up using the ECS system (Entity Component System) in combination with C# Jobs (multithreaded)
Use the Profiler (Window -> Profiler) or (Window -> Analysis -> Profiler in 2018.3) to analyse what's actually taking long.
A for-each is bad (garbage-collection wise) compared to a normal for.
If you set position and rotation, group the two calls by using SetPositionAndRotation
Note null check with UnityEngine.Object children are NOT the standard C# null checks. This description that Jetbrains provides in relation to the Rider IDE and analysis tool gets into the details. The basic idea is that the C# script hands off the null check to the underlying C++ engine structure.
I have not had the need for it but I have seen other's code that keeps a simple list of UnityEngine.Object references. They add a reference to the object to the list when it is created. Then remove it from the list on destruction. Update() can then use a faster test in the list. Where speed is critical, you just test the list not the object. Of course, an approach other than a list could be used.
I looked it up and tested it and yes you can do this with a callback function which will be registered to your target's OnDestroy method. Your Player script should access target script and delegate the method like this:
public GameObject target;
private TargetScript myTargetScript;
void Start () {
myTargetScript = target.GetComponent<TargetScript>();
myTargetScript.OnDestroyEvnt += OnDestroyListener;
}
private void OnDestroyListener(MonoBehaviour instance)
{
Debug.Log("Callback is called");
}
Also Target script should be like this:
public event OnDestroyDelegate OnDestroyEvnt;
public delegate void OnDestroyDelegate(MonoBehaviour instance);
void Start () {
StartCoroutine(DestroyCoroutine());
}
private void OnDestroy()
{
if (this.OnDestroyEvnt != null)
{
this.OnDestroyEvnt(this);
}
}
IEnumerator DestroyCoroutine()
{
yield return new WaitForSeconds(5);
Destroy(gameObject);
}
I used a coroutine to destroy the object after 5 secs. It is actually irrelevant in your case. I adopted this code from here.
You can avoid it logic-wise, make a coroutine that only runs when you assign the target, and if the target is null, end the coroutine, that coroutine should have a...
yield return new WaitForEndOfFrame();
that way it will act as a kind of LateUpdate.
And check every frame...
while (target != null)
You would be still checking every frame the null, but you will only check the target = null once.
I'm using GWTP, adding a Contract layer to abstract the knowledge between Presenter and View, and I'm pretty satisfied of the result with GWTP.
I'm testing my presenters with Mockito.
But as time passed, I found it was hard to maintain a clean presenter with its tests.
There are some refactoring stuff I did to improve that, but I was still not satisfied.
I found the following to be the heart of the matter :
My presenters need often asynchronous call, or generally call to objects method with a callback to continue my presenter flow (they are usually nested).
For example :
this.populationManager.populate(new PopulationCallback()
{
public void onPopulate()
{
doSomeStufWithTheView(populationManager.get());
}
});
In my tests, I ended to verify the population() call of the mocked PopulationManager object. Then to create another test on the doSomeStufWithTheView() method.
But I discovered rather quickly that it was bad design : any change or refactoring ended to broke a lot of my tests, and forced me to create from start others, even though the presenter functionality did not change !
Plus I didn't test if the callback was effectively what I wanted.
So I tried to use mockito doAnswer method to do not break my presenter testing flow :
doAnswer(new Answer(){
public Object answer(InvocationOnMock invocation) throws Throwable
{
Object[] args = invocation.getArguments();
((PopulationCallback)args[0]).onPopulate();
return null;
}
}).when(this.populationManager).populate(any(PopulationCallback.class));
I factored the code for it to be less verbose (and internally less dependant to the arg position) :
doAnswer(new PopulationCallbackAnswer())
.when(this.populationManager).populate(any(PopulationCallback.class));
So while mocking the populationManager, I could still test the flow of my presenter, basically like that :
#Test
public void testSomeStuffAppends()
{
// Given
doAnswer(new PopulationCallbackAnswer())
.when(this.populationManager).populate(any(PopulationCallback.class));
// When
this.myPresenter.onReset();
// Then
verify(populationManager).populate(any(PopulationCallback.class)); // That was before
verify(this.myView).displaySomething(); // Now I can do that.
}
I am wondering if it is a good use of the doAnswer method, or if it is a code smell, and a better design can be used ?
Usually, my presenters tend to just use others object (like some Mediator Pattern) and interact with the view. I have some presenter with several hundred (~400) lines of code.
Again, is it a proof of bad design, or is it normal for a presenter to be verbose (because its using others objects) ?
Does anyone heard of some project which uses GWTP and tests its presenter cleanly ?
I hope I explained in a comprehensive way.
Thank you in advance.
PS : I'm pretty new to Stack Overflow, plus my English is still lacking, if my question needs something to be improved, please tell me.
You could use ArgumentCaptor:
Check out this blog post fore more details.
If I understood correctly you are asking about design/architecture.
This is shouldn't be counted as answer, it's just my thoughts.
If I have followed code:
public void loadEmoticonPacks() {
executor.execute(new Runnable() {
public void run() {
pack = loadFromServer();
savePackForUsageAfter();
}
});
}
I usually don't count on executor and just check that methods does concrete job by loading and saving. So the executor here is just instrument to prevent long operations in the UI thread.
If I have something like:
accountManager.setListener(this);
....
public void onAccountEvent(AccountEvent event) {
....
}
I will check first that we subscribed for events (and unsubscribed on some destroying) as well I would check that onAccountEvent does expected scenarios.
UPD1. Probably, in example 1, better would be extract method loadFromServerAndSave and check that it's not executed on UI thread as well check that it does everything as expected.
UPD2. It's better to use framework like Guava Bus for events processing.
We are using this doAnswer pattern in our presenter tests as well and usually it works just fine. One caveat though: If you test it like this you are effectively removing the asynchronous nature of the call, that is the callback is executed immediately after the server call is initiated.
This can lead to undiscovered race conditions. To check for those, you could make this a two-step process: when calling the server,the answer method only saves the callback. Then, when it is appropriate in your test, you call sometinh like flush() or onSuccess() on your answer (I would suggest making a utility class for this that can be reused in other circumstances), so that you can control when the callback for the result is really called.