High CPU Usage in React-Native - xcode

I'm working to reduce the CPU load on an RN app. I've built the app to a device, in release, and trimmed the console logs from the project. Even after doing this the app is still around 33% CPU usage mostly on a blank screen.
The interesting part is that occasionally, about after 6 minutes, the CPU frees up and drops to 3-4%. I suspect that a really long loop has completed but I am unable to find it.
I've run the app in Xcode's Instruments, it's only on iOS atm, and found some interesting things. From the looks of it, it's gotten into a long chain of [CALayer renderInContext] which is coming from UVVideoRecorder. I'm not familiar with UVVideoRecorder and would love to hear any thoughts people might have.
Call Stack + Threads

I suggest using Why Did You Render which will help you track when and why every component re-render ... and hence catch unnecessary re-renders to optimize it....

I think profiling can help you with this. You can get detailed information about work done in the JavaScript thread and main thread side-by-side.
Profiling in React Native - https://reactnative.dev/docs/profiling

Related

Xamarin high memory usage

I'm developing an app in Xamarin, but when I show a map on a page it doubles the memory usage.
When I pop the page and open it again, it increases even more.
Now It seems to be fixed when I use the garbage collector GC.Collect();
I was wondering when it's the best moment to call it.
Personally I was thinking about putting it in onAppearing().
But I'm not sure if it can cause problemns (like it collecting things I still need) or if this is the right way to solve the high memory usage problem.
Calling GC.Collect() is something that shouldn't be done by the developer manually but sometimes necessary when it comes to Xamarin. But instead of calling it in OnAppearing I would recommend to call it in OnDisappearing instead.
If you are in the mood I would suggest that you use OnDisappering to clean-up any references or instances you don't need any more for that page. Than compare your memory-usage and see if that helps too. The reason why I prefer that way over calling GC.Collect is: GC.Collect halts every process your app runs. The more work the collecting has to do the longer your app pauses and my be feeling unresponsive and slow to the user.

Updating the complication gradually degrades the Apple Watch app performance in watchOS3

I've been stressing over this issue for about a week now, trying to pin point the source of a slow but steady Apple Watch app performance degradation. Over the course of about two days, my app's UI would become progressively more sluggish. I've narrowed it down to a complication update code. Even if I strip down the complication update to an absolute bare minimum, this problem still happens, albeit slower than if I update the complication with some actual data. I update the complication every 10 minutes. Once the new data comes, I simply execute
for (CLKComplication *comp in [CLKComplicationServer sharedInstance].activeComplications) {
[[CLKComplicationServer sharedInstance] reloadTimelineForComplication:comp];
}
which in turn calls:
- (void)getCurrentTimelineEntryForComplication:(CLKComplication *)complication withHandler:(void(^)(CLKComplicationTimelineEntry * __nullable))handler {
...
}
This works fine, the new data displays, but when repeated a few dozen times, the UI responsiveness of the main app begins to noticeably degrade, and when it's repeated about a hundred times (which happens in less than a day with 10 minute updates) the UI really slows down significantly.
I have nothing fancy going on with the complication structure - no time travel, just display the current data, and everything is set up for that. To make sure I'm not looking at the wrong place, I've made a test that reloads the timeline every second, and in this test, my getCurrentTimelineEntryForComplication looks like this:
- (void)getCurrentTimelineEntryForComplication:(CLKComplication *)complication withHandler:(void(^)(CLKComplicationTimelineEntry * __nullable))handler {
handler(nil);
}
so there's literally nothing going there, just send back the empty handler. Yet, even in this scenario, after a hundred or so timeline reloads, the main app's UI slows down visibly.
Some other things to note:
If I'm not updating the complication, the app's UI performance never degrades, no matter how many times I open it, or how long I use it, or how many times the data fetching code runs in the background.
When testing this in the simulator, I can't get the performance degradation to happen, but I can consistently see that there's a small, but steady memory leak coming from the complication update (again, this happens no matter how simple update I do inside the getCurrentTimelineEntryForComplication method.
Has anyone else noticed this, and is there any hope to deal with it? Am I doing something wrong? For the time being I make sure only to update the complication if the data has changed, but that just postpones the problem, rather than solving it.
Oct 24 edit
I've done more careful testing on a real watch, and while before for some reason I didn't notice the memory leak associated with this on a real watch, I have now definitely seen it happen. The real device mirrors the issue seen on the simulator completely, just with a different initial amount of memory allocation.
Again, all I do is call reloadTimelineForComplication on a constant loop, and the complication is updated with a single line of text from a cached data object, and the complication controller is otherwise stripped to a bare minimum. When the complication is removed from the watch face, memory leak predictably stops.
My main project is written in ObjectiveC, but I have repeated the test with a test project made in Swift, and there are no differences. Also, the problem persists with the latest XCode 8.1 GM and the watchOS 3.1 beta that's supplied with the simulator that comes with it, as well as running it on a real watch with watchOS3.1 installed.
Jan 24, 2017 edit
Sadly, the issue persists in watchOS 3.1.3, completely unchanged. In the meantime I've contacted Apple's code-level support, sent them sample code, and they've confirmed that the problem exists, and told me to file a bug report. I did file a bug report about two months ago, but up until now it remains unclassified, which I guess means no one looked at it yet.
Jan 31, 2017 edit
Apple has fixed the problem in watchOS3.2 beta 1. I've been testing it both in the simulator and on real watch. Everything's working great, no memory leaks or performance degradation anymore. In the end there were no workarounds for this, until they decided to fix it.
Apple has fixed the problem in watchOS3.2 beta 1. I've been testing it both in the simulator and on real watch. Everything's working great, no memory leaks or performance degradation anymore. In the end there were no workarounds for this, until they decided to fix it.
I noticed that using the native calendar complication everything i do becomes very sluggish. So maybe it's a bug in the new watch OS.
After using the calendar complication for a couple of days it's impossible to use that watch face. Even if I change to another complication and switch back to the calendar one it doesn't "reset" the performance. The only thing that solves is to reboot the watch. (or forget about the calendar and use another complication instead)

Best practices for Document Based Core Data application that takes a long time to open

I have an OS X Cocoa cpplication (10.8-10.9) that opens very large NSDocument (Core Data backed) files that are about 2 GBs or bigger. This takes about 20-40 seconds with the initial load of the document, but then is pretty snappy. The 20-40 seconds doesn't exactly jive with a good UI experience, so I'd like to fix that.
I would like to either A) make the document opening faster, or B) show a "loading" screen.
I'm wondering what (if anything) folks have done to A) make opening a core data document faster (even if its doing stuff in the background) or B) display a splash screen / progress bar during the opening process.
WRT to B) (not a 2-part question, really, just wanted to demonstrate I have do research) showing a splash screen by creating methods in the NSDocument class works if calling during: windowControllerWillLoadNib and windowControllerDidLoadNib methods, but only after the first document has been opened (I'm sure there is a workaround). Either way, there is no "progress" that I can see that I could establish a hook into, anyway.
What does -getLociWithChromsomes: do? What happens when you drill into that method in Instruments to see what is taking all the time?
Same question with -GetAllLoci: and -getMaxLocusSnps?
It appears from the small amount of data that I can see is that you are doing a ton of fetching on launch. That is a bad design no matter what platform you are on. You should avoid doing a lot of fetching during the launch of the document and delay it until after the initial document/application launch has completed.
You could use a multi-threaded design here and it probably would help but it is really masking the problem.
The core of the issue appears to be that you are trying to do too much on launch. I am not certain that the entire delay is in core data or what you are doing with the data once it is retrieved as I do not have code level access through the trace you provided. It would be interesting to see screenshots of those methods above in Instruments with the time percentages highlighted.
Update
Again, you are loading too much during launch and blocking the UI. You have three answers all saying the same basic thing. This is not a Core Data problem. This is a performance problem because you are loading too much on launch or you are doing too heavy of a calculation on launch.
In addition to the specific hints Duncan gave you it's always useful to check out the latest (and free) WWDC videos on ADC to get an idea on the patterns provided by OS X and Cocoa in particular to boost an apps performance. Some starting points:
WWDC '12
- Asynchronous Design Patterns with Blocks, GCD, and XPC
WWDC '13
- Designing Code for Performance
Try opening the store on a background thread and once it's open activate the UI - that seems to work OK.
I create a background thread to call the [psc addPersistentStoreWithType:configuration:URL:options:error:] and once that's complete I hand control back to the main thread where the managedObjectContext gets created and the UI enabled.
You face this issue if Core Data has to do a big upgrade to a new model version as well. Some of my files take around a minute and if they are in iCloud it can be even longer. And if the upgrade happens on an iOS device then it can take a few minutes so this seems to be important for iOS apps as well.
BTW I have posted sample apps here
http://ossh.com.au/design-and-technology/software-development/sample-library-style-ios-core-data-app-with-icloud-integration/

Periodic GPU performance problem

I have a WinForms application that uses XNA to animate 3D models in a control. The app have been doing just fine for months but recently I've started to experience periodic pauses in the animation. Setting out to investigate what is going on I have established these facts:
It happens on my machine only, other machines works fine
Removing everything from my render loop does not improve the problem
In 2. I didn't actually remove everything, I limited my loop to set the viewport on my GraphicsDevice and then do a GraphicsDevice.Present.
Trying to dig further I fired up PIX to capture some statistics. Screenshots of two PIX runs can be viewed here (Run6) and here (Run14). Run6 is using my original render loop and Run14 is using the bare-bones Present loop.
PIX tells me that the GPU is periodically doing something, and I assume this is causing the pauses. What could be the cause of this? Or how do I go about finding out what the GPU is actually doing?
Update: since I usually trust my code to be perfect (who's laughing?) I started a new XNA project from scratch to see if it exhibit the same behavior. So starting a new XNA 3.1 Windows Game project and running PIX I get this timeline. The same periodic pauses. So the problem must be lower in the stack, in XNA or Direct3D.
So PIX shows that the GPU is working on something, I can see the list of DX calls made within each frame and the timing calculations shows that the pause occurs during (or after) the IDirect3DDevice9::Present call.
Update 2: I had previously installed and uninstalled XNA 4.0 CTP on the problematic machine. I cannot be certain that this is related but I thought that perhaps a reinstall of the XNA Game Studio 3.1 bits could make a difference. Turns out it did.
The underlying question remains the same (and the bounty is still up): what could affect XNA 3.1 (or DirectX) to make it behave like this and is there any logging/tracing power tool for the DirectX and/or GPU level out there that could shed some light on what is going on?
Note: I'm using XNA 3.1 on a Windows 7 x64 dual-core machine with 8GB RAM.
Note2: also posted this question on the XNA Creators forums here.
You could try to see if you can find something with Xperf that is close to your periodically problem, do not run your application but keep the programs open that would normally run besides your application. You could also try to do it again with the application running but it could give a cluttered view.
Start the tracing, do this in an elevated prompt.
xperf -on BASE+LATENCY -stackWalk Profile
Wait for a fair amount of time to be sure that the problem is traced.
Stop the tracing and open it like this.
xperf -d trace.etl
xperfview trace.etl
Analyze by looking at the graphs and consulting tables of specific intervals and see if you can find something that is related to the problem, the highest chance on finding it would be in the DPC and Interrupts section. But it might as well be something odd at the CPU or I/O section. Good luck!
Also more information on Xperf and how to obtain it, hopefully this delivers results.
If not, you can alternatively try GPUView which has been used for improvements in DWM,
this is also included next to Xperf with the Windows Performance Toolkit so you can easily try both!
log v
... wait for a fair amount of time to be sure that the problem is traced ...
log
gpuview merged.etl
In the case that gpuview gets out of memory you can try to add "/limit 3" or remove the v.
Read the documentation of the tools if you are stuck somewhere.
Hmm ... this seems to be occurring on the GPU, however it sounds like a CPU garbage collection issue. Can you run the CLR profiler and see if you can see any spikes in GC activity that you can correlate to the slowdowns?
I agree that it sounds unlikely since you can clearly see it in PIX, but it might offer a clue as to the cause.
If it's only happening on your own machine, then could it be drivers? Forgive me for being skeptical, but it's a 64 bit machine after all :D
This looks like either a vsync issue or GPU in its last throes. Since going back to a different version fixed it, and the "bottleneck" is in IDirect3DDevice9::Present lets go with the former option.
I'm not familiar with XNA so I don't know how much of the workings of D3D are exposed, but do you know what your PresentationParameters are set to?
Specifically try setting the swap effect set to Discard.

Handling very large SFTP uploads - Cocoa

I'm working on a small free Cocoa app that involves some SFTP functionality, specifically working with uploads. The app is nearing completion however I've run into a pretty bad issue with regards to uploading folders that contain a lot of files.
I'm using ConnectionKit to handle the uploads:
CKTransferRecord * record;
record = [connection recursivelyUpload:#"/Users/me/large-folder"
to:#"/remote/directory"];
This works fine for most files and folders. Although in this case #"/Users/me/large-folder" has over 300 files in it. Calling this method spins my CPU up to 100% for about 30 seconds and my application is unresponsive (mac spinning ball). After the 30 seconds my upload is queued and works fine, but this is hardly ideal. Obviously whatever is enumerating these files is causing my app to lock up until it's done.
Not really sure what to do about this. I'm open to just about any solution - even using a different framework, although I've done my research and ConnectionKit seems to be the best of what's out there.
Any ideas?
Use Shark. Start sampling, start downloading, and as soon as the hang ends, stop sampling.
If the output confirms that the problem is in ConnectionKit, you have two choices:
Switch to something else.
Contribute a patch that makes it not hang.
The beauty of open-source is that #2 is possible. It's what I recommend. Then, not only will you have a fast ConnectionKit, but once the maintainers accept your patch, everyone else who uses CK can have one too.
And if Shark reveals that the problem is not in ConnectionKit (rule #2 of profiling: you will be surprised), then you have Shark's guidance on how to fix your app.
Since the problem is almost certainly on the enumeration, you'll likely need to move the enumeration into an asynchronous action. Most likely they're using NSFileManager -enumeratorAtPath: for this. If that's the main problem, then the best solution is likely to move that work onto its own thread. Given the very long time involved, I suspect they're actually reading the files during enumeration. The solution to that is to read the files lazily, right before uploading.
Peter is correct that Shark is helpful, but after being a long-time Shark fan, I've found that Instruments tends to give more useable answers more quickly. You can more easily add a disk I/O and memory allocation track to your CPU Sampler using Instruments.
If you're blocking just one core at 100%, I recommend setting Active Thread to "Main Thread" and setting Sample Perspective to "All Sample Counts." If you're blocking all your cores at 100%, I recommend setting Active Thread to "All Threads" and Sample Perspective to "Running Sample Times."

Resources