I have such problem with my application that´s running in real time.
It´s getting values an plotting two graphs. Also is updating a few (8) QLabels and displaying them in window. The application should run for a very long time and processing data so I wanted to test it in faster regime and I set the sending values to the application for each 10ms. When I start the application everything works fine, but after some time QLabels stuck or plotting graphs stuck and in the end application crashes.
I would like to ask if 10ms is too fast for updating QLabels and graphs (QCustomPlot) and that is the reason of crashing the program or I need to search for the problem somewhere else?
void mainWnd::useDataFromPipe(double val) {
if(val<=*DOF) {
FSOcounter=FSOcounter+1.0;
lastRecievedFSO->saveValue(val);
updateGraphMutex->lock();
FSOvectorXshort->replace(1, FSOcounter);
updateGraphMutex->unlock();
if(!firstDataFSO()) {
if(val>maximumRecievedFSO->loadValue()) maximumRecievedFSO->saveValue(val);
else if(val<minimumRecievedFSO->loadValue()) minimumRecievedFSO->saveValue(val);
}
else {
maximumRecievedFSO->saveValue(val);
minimumRecievedFSO->saveValue(val);
}
numberOfRecievedValuesFSO->saveValue(numberOfRecievedValuesFSO->loadValue()+1.0);
}
else {
RFcounter=RFcounter+1.0;
lastRecievedRF->saveValue(val);
updateGraphMutex->lock();
RFvectorXshort->replace(1, RFcounter);
updateGraphMutex->unlock();
if(!firstDataRF()) {
if(val>maximumRecievedRF->loadValue()) maximumRecievedRF->saveValue(val);
else if(val<minimumRecievedRF->loadValue()) minimumRecievedRF->saveValue(val);
}
else {
maximumRecievedRF->saveValue(val);
minimumRecievedRF->saveValue(val);
}
numberOfRecievedValuesRF->saveValue(numberOfRecievedValuesRF->loadValue()+1.0);
}
}
where saveValue() and loadValue() are
void infoLine::saveValue(double val) {
*value=val;
valueLabel->setText(QString("<b>%1</b>").arg(val));
}
double infoLine::loadValue(void) {
return *value;
}
You're not "updating" the labels every 10ms, you're merely calling setText or similar methods on them every 10ms. The labels will be updated as dictated by how many events are in the event queue. As long as you "update" the labels by calling setText etc., you're OK - this should not be a problem.
A crash is usually due to a memory bug. A memory bug typically can be due to running out of memory, a double free, or access to deallocated memory.
What you describe seems like a memory bug due to running out of memory. The most trivial explanation is that you're leaking memory. That's an easy one - smart pointers (QScopedPointer and QSharedPointer) will help with that.
You may also not be leaking memory, but recursing too deeply if you indeed recurse into the event loop.
You may also be updating the widget(s) incorrectly, resulting in forced, repeated, expensive repaints that are not compressed into one repaint.
You'd need to show how you "update" the plot. While the labels are implemented correctly, and repeated calls to various QLabel setXxxx methods are cheap, the custom plot class may simply be implemented incorrectly.
The idiomatic, and indeed the only correct way of updating a widget in Qt is:
Set some data members.
Call update().
This is what QLabel::setText does internally, and it is what any other widget should be doing as well. This functionality should be exposed in a setXxxx-like method, and is an implementation detail, although an important one. The users of the widget don't need to be aware of it.
The update events are posted to the widget and are compressed, such that repeated updates without returning to the event loop result in only one repaint.
It's really hard to tell without seeing a self-contained, minimal example. By minimal I mean nothing that has no bearing on the issue should be left in.
Related
I have some UI testing which involves text manipulation in a NSTextView. I'm current setting the XCUIElement via:
let sqlTextViewTextView = sqlWindow.textViews["SQL text view"]
This works fine, but in one of the tests, a bunch of text is entered, then deleted one character at a time.
sqlTextViewTextView.typeText(substring)
// Delete backwards until we are clear
while(true)
{
let targetString:String = sqlTextViewTextView.value as! String
if(0 == targetString.characters.count)
{
break;
} // End of we have no targetString
sqlTextViewTextView.typeKey(XCUIKeyboardKeyDelete, modifierFlags:.None)
} // End of we have text entered
This ends up being extremely slow, as every call to sqlTextViewTextView evaluates the query to find the element.
Is there a way I can "cache" the element to skip querying it during this tight loop?
Testing code is (probably poorly written) Swift 2. I did not tag the question as such, because its not a swift specific question.
The query through the hierarchy should be pretty close to instantaneous. It's much more likely that the runtime of your test is being affected by the UI Testing app's logic of waiting until the target app idles every time it takes an action (in this case, every time you hit the XCUIKeyboardKeyDelete).
You can isolate this by timing the elements of the loop; I would be astonished if the query itself takes substantial time, but if it does, could you tell us what the view hierarchy of your app looks like? If you have an enormous number of view elements, it may speed up the query to use more specific set of selectors rather than trawling the full hierarchy.
I have few comboboxes with very dig data sets within ~ 100K rows and more. I tried it with QStandardItemModel - works fast enough if model is preloaded, also model loading takes few seconds if performed in separate thread. Tried comboboxes with QSqlQueryModel without threading to improve performance but experienced it works much slower than QStandardItemModel (in our project QSqlQueryModel works very fast with such amount of data with QTreeView for example). What could be the problem here? Is there a way to speed-up combobox, some parameters?
P.S. Suggested by Qt doc QComboBox::AdjustToMinimumContentsLengthWithIcon does not speed things much: dialog with such combos starts too long and exits 10-20 sec. AdjustToMinimumContentsLength works a little bit faster but anyway delays are too long.
Found the solution. 1st thought was to find what model will work faster, for example QStringListModel to replace QStandardItemModel or QSqlQueryModel. However seems that they work almost same speed. 2nd I found in Qt doc that combobox by default uses QStandardItemModel to store the items and a QListView subclass displays the popuplist. You can access the model and view directly (with model() and view()). That was strange for me as I know QTreeView works just fine with even bigger amount of data, and simpler QListView also inherited from QAbstractItemView should do this as well. I start to digg into QListView and found properties in it which had solved the problem: now combobox opens immediately on large amount of data. Static function was written to tweak all of such combos (comments with explanation are from Qt doc):
void ComboboxTools::tweak(QComboBox *combo)
{
// For performance reasons use this policy on large models
// or AdjustToMinimumContentsLengthWithIcon
combo->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLength);
QListView *view = (QListView *)combo->view();
// Improving Performance: It is possible to give the view hints
// about the data it is handling in order to improve its performance
// when displaying large numbers of items. One approach that can be taken
// for views that are intended to display items with equal sizes
// is to set the uniformItemSizes property to true.
view->setUniformItemSizes(true);
// This property holds the layout mode for the items. When the mode is Batched,
// the items are laid out in batches of batchSize items, while processing events.
// This makes it possible to instantly view and interact with the visible items
// while the rest are being laid out.
view->setLayoutMode(QListView::Batched);
// batchSize : int
// This property holds the number of items laid out in each batch
// if layoutMode is set to Batched. The default value is 100.
}
I just noticed today that this method, Flush() is available.
Not able to find detailed documentation on it.
What exactly does this do?
Is this required?
gl.flush in WebGL does have it's uses but it's driver and browser specific.
For example, because Chrome's GPU architecture is multi-process you can do this
function var loadShader = function(gl, shaderSource, shaderType) {
var shader = gl.createShader(shaderType);
gl.shaderSource(shader, shaderSource);
gl.compileShader(shader);
return shader;
}
var vs = loadShader(gl, someVertexShaderSource, gl.VERTEX_SHADER);
var fs = loadShader(gl, someFragmentShaderSource, FRAGMENT_SHADER);
var p = gl.createProgram();
gl.attachShader(p, vs);
gl.attachShader(p, fs);
gl.linkProgram(p);
At this point all of the commands might be sitting in the command
queue with nothing executing them yet. So, issue a flush
gl.flush();
Now, because we know that compiling and linking programs is slow depending on how large and complex they are so we can wait a while before trying using them and do other stuff
setTimeout(continueLater, 1000); // continue 1 second later
now do other things like setup the page or UI or something
1 second later continueLater will get called. It's likely our shaders finished compiling and linking.
function continueLater() {
// check results, get locations, etc.
if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS) ||
!gl.getShaderParameter(fs, gl.COMPILE_STATUS) ||
!gl.getProgramParameter(p, gl.LINK_STATUS)) {
alert("shaders didn't compile or program didn't link");
...etc...
}
var someLoc = gl.getUniformLocation(program, "u_someUniform");
...etc...
}
I believe Google Maps uses this technique as they have to compile many very complex shaders and they'd like the page to stay responsive. If they called gl.compileShader or gl.linkProgram and immediately called one of the query functions like gl.getShaderParameter or gl.getProgramParameter or gl.getUniformLocation the program would freeze while the shader is first validated and then sent to the driver to be compiled. By not doing the querying immediately but waiting a moment they can avoid that pause in the UX.
Unfortunately this only works for Chrome AFAIK because other browsers are not multi-process and I believe all drivers compile/link synchronously.
There maybe be other reasons to call gl.flush but again it's very driver/os/browser specific. As an example let's say you were going to draw 1000 objects and to do that took 5000 webgl calls. It likely would require more than that but just to have a number lets pick 5000. 4 calls to gl.uniformXXX and 1 calls to gl.drawXXX per object.
It's possible all 5000 of those calls fit in the browser's (Chrome) or driver's command buffer. Without a flush they won't start executing until the the browser issues a gl.flush for you (which it does so it can composite your results on the screen). That means the GPU might be sitting idle while you issue 1000, then 2000, then 3000, etc.. commands since they're just sitting in a buffer. gl.flush tells the system "Hey, those commands I added, please make sure to start executing them". So you might decide to call gl.flush after each 1000 commands.
The problem though is gl.flush is not free otherwise you'd call it after every command to make sure it executes as soon as possible. On top of that each driver/browser works in different ways. On some drivers calling gl.flush every few 100 or 1000 WebGL calls might be a win. On others it might be a waste of time.
Sorry, that was probably too much info :p
Assuming it's semantically equivalent to the classic GL glFlush then no, it will almost never be required. OpenGL is an asynchronous API — you queue up work to be done and it is done when it can be. glFlush is still asynchronous but forces any accumulated buffers to be emptied as quickly as they can be, however long that may take; it basically says to the driver "if you were planning to hold anything back for any reason, please don't".
It's usually done only for a platform-specific reason related to the coupling of OpenGL and the other display mechanisms on that system. For example, one platform might need all GL work to be ordered not to queue before the container that it will be drawn into can be moved to the screen. Another might allow piping of resources from a background thread into the main OpenGL context but not guarantee that they're necessarily available for subsequent calls until you've flushed (e.g. if multithreading ends up creating two separate queues where there might otherwise be one then flush might insert a synchronisation barrier across both).
Any platform with a double buffer or with back buffering as per the WebGL model will automatically ensure that buffers proceed in a timely manner. Queueing is to aid performance but should have no negative observable consequences. So you don't have to do anything manually.
If you decline to flush and don't strictly need to even when you semantically perhaps should, but your graphics are predicated on real-time display anyway, then you're probably going to be suffering at worst a fraction of a second of latency.
I've got a relatively fast SproutCore app that I'm trying to make just a tad bit faster.
Right now, when the user scrolls my SC.ListView and they scroll into view some list items that have not been loaded from the server (say from a relationship), the app automatically makes a call to the server to load these records. Even though this is fast, there is still a short period of time where my list items are blank.
I know that I can make them say "Loading..." or something like that (and I have), but I was wondering: is there was a way to pre-load my "off-screen" records so that as the user scrolls, the list items are already loaded?
My ListItemViews will be fairly large (pixel-wise), so even loading double the amount of data is not going to be killer from an AJAX perspective, and it would be nice if as the user scrolled, the content was always loaded (unless they scroll SUPER-SUPER-fast, in which case I'm okay with them seeing a loading indicator).
I currently found a solution by adding the following to my SC.ListView, but I've noticed some major performance issues on mobile and they are directly related to making this change, so I was wondering if there was a better way.
contentIndexesInRect: function(rect) {
rect.height = rect.height * 2;
return sc_super();
}
Overriding contentIndexesInRect is the way I would do this. I would do less than double it though – I might get the result from sc_super() and then add a few extra items to the resulting index set. (I believe it comes back frozen, so you may have to clone-edit-freeze.) One or two extra may give you enough breathing room to get the stuff loaded, without contributing nearly as much to the apparent performance issue.
I'm surprised that it results in major performance issues though. It sounds to me like your list items themselves may be heavier-weight than they need to be – for example, they may have a lot of bindings to hook and unhook. If that's what's going on, you may benefit more from improving their efficiency.
I think you would be better served to load the additional data outside of the context of what the list is actually displaying. For instance, forcing more list items to render in order to trigger additional requests does result in having the extra data available, but also adds several unnecessary elements to the DOM, which is actually detrimental to overall performance. In fact these extra elements are most likely the cause of the major slowdown on mobile once you get to a sufficient number of extras.
Instead, I would first ensure that your list item views are properly pooling so that only the visible items are updating in place with as little DOM manipulation as possible. Then second, I would lazily load in additional data only after the required data is requested. There are quite a few ways to do this depending on your setup. You might want to add some logic to a data source to trigger an additional request on each filled request range or you might want to do something like override itemViewForContentIndex in SC.CollectionView as the point to trigger the extra data. In either case, I imagine it could look something like this,
// …
prefetchTriggered: function (lastIndex) {
// A query that will fetch more data (this depends totally on your setup).
var query = SC.Query.remote(MyApp.Record, {
// Parameters to pass to the data source so it knows what to request.
lastIndex: lastIndex
});
// Run the query.
MyApp.store.find(query);
},
// …
As I mention in the comments above, the structure of the request depends totally on your setup and your API so you'll have to modify it to meet your needs. It will work better if you are able to request a suitable range of items, rather than one-at-a-time.
I noticed that, if in WP7 application I press Start key then quickly Back key to return to the app, and very quickly repeat these steps many times, the application ends up being crashed (it exits unexpectedly and no way to recover it via Back key). This happens on device (never seen on emulator), and it takes 10-15 steps before the application gets shut down.
I follow Microsoft guidelines about saving / restoring its state. Furthermore, all other apps I've tried in such way crash too. However, some apps are much harder to kill in this way than the others. During experiments with this stress test, I noticed that XNA games tend to be less resistant than pure Silverlight appsThe more data the application saves / recovers, the less resistant it is
Unfortunately, my XNA game has to save a lot of data during deactivation, and it's pretty easy to get it crashed.
Does anyone know if it's a known problem or something else?
I'd appreciate any advice of how to make the game more stable if it's not possible to completely eliminate the problem.
I found a workaround how to make the application a bit more stable. Actually, we don't want to save game data to the isolated storage each time during deactivation. It's only needed when game state was changed. As my game is automatically paused after being activated, it's state didn't changed, and I don't have to save its data again until the user resumes the game. Thus, storing data to isolated storage occurs for the first deactivation only. This approach helped a little, but not too much. 20 iterations of Start key / Back key still make it go down.
On the Idea that the Problem could lay within the De/-Serialization Process you could do this:
private IsolatedStorageSettings isosettings = IsolatedStorageSettings.ApplicationSettings;
void Application_deactivated()
{
isosettings.Add("serialization_finished", false);//just add once,
//after that use isosettings["serialization_finished"]
//DO: save here your code into isostorage
isosettings["serialization_finished"] = true;
}
void Application_activated()
{
while (!isosettings["serialization_finished"])
Thread.Sleep(500);
//DO: read you data from isostorage
}
So you practically build an on/off switch to test if the serialization-process is finished
Old:
The Tombstoning has a Timelimit in which he must be finished (10
seconds). My guess is here that you give him so much to tombstone that
at one point one instance of the application cannot finish the
tombstoning in time. But thats just an assumption on the premise that
the more to save = faster to crash.
You could test that by measuring the time you need for the tombstoning
and writing the data into the isolatedstorage. When you analyze the
data and see that the time for the tombstoning increases (up to 8-9
seconds) you can conclude that it should be the time.
On the other hand, if the time needed never increases and stays within
some seconds you can safely conclude that it shouldnt be a timeproblem