|
|
Home » U++ Library support » ArrayCtrl, HeaderCtrl & GridCtrl » GridCtrl performance
GridCtrl performance [message #39737] |
Mon, 22 April 2013 16:36  |
crydev
Messages: 151 Registered: October 2012 Location: Netherlands
|
Experienced Member |
|
|
Hello,
I am working on a memory scanner project. I use a GridCtrl to visualize the results from a scan to the user. However, I notice that the ArrayCtrl, as well as the GridCtrl are very slow when it comes to adding ~300.000+ items at once. I have 8 threads scanning the memory so the scan is done very fast. The adding and removing of the items from the list however, is slow.
Is there a way to make it faster? Why is it so slow?
Thanks,
Crydev
|
|
|
|
|
Re: GridCtrl performance [message #39744 is a reply to message #39743] |
Mon, 22 April 2013 22:50   |
|
GridCtrl uses Vector<Vector<Item>> internally. So inserting is as fast as Vector implementation is. You should observe dramatic speed improvement if you compile your app in release mode (but I assume you did ). If you insert many rows at once you can put insertion part between grid.Ready(false) and grid.Ready(true).
You can also add 300.000 empty rows to the grid in the beginning and simply clear and set particular cells. This way you would avoid removing and inserting rows over and over again.
ArrayCtrl and virtual rows should solve your problem. It seems like you did something wrong, but without the real code it's hard to tell.
|
|
|
|
Re: GridCtrl performance [message #39774 is a reply to message #39743] |
Thu, 25 April 2013 16:47   |
Sender Ghost
Messages: 301 Registered: November 2008
|
Senior Member |
|
|
Hello.
crydev wrote on Mon, 22 April 2013 22:25 |
BioBytes wrote on Mon, 22 April 2013 21:43 | Hello Crydev,
Did you try SetVirtualCount method in ArrayCtrl ?
Regards
Biobytes
|
Yes I tried using it but unfortunately it didn't solve my problem. If I could safely use the multithreaded structure to fill up my GridCtrl it would speed up very much but because it is GUI it isn't possible.
|
I don't know how you tried it, but try again.
Below is additional example of VirtualArray reference application:
Toggle Spoiler
#include <CtrlLib/CtrlLib.h>
using namespace Upp;
int count = 0x100000;
Vector<String> data;
template <String (GetData) (int index)>
struct NumberToText : public Convert {
virtual Value Format(const Value& q) const {
return GetData(int(q));
}
};
String GetIndexData(int index)
{
ASSERT(index >= 0 && index < data.GetCount());
return data[index];
}
String GetReverseData(int index)
{
ASSERT(index >= 0 && index < data.GetCount());
return data[count - index - 1];
}
String FormatData(int index)
{
return NFormat("Data #%d", index + 1);
}
class App : public TopWindow {
public:
typedef App CLASSNAME;
App();
// Ctrls
ArrayCtrl list;
Button btnAdd, btnRemove;
// Events
void OnAdd();
void OnRemove();
};
const int addition = count / 2;
void App::OnAdd()
{
const int prevCount = count;
count += addition;
data.SetCount(count);
for (int i = prevCount; i < count; ++i)
data[i] = FormatData(i);
list.SetVirtualCount(count);
}
void App::OnRemove()
{
count -= addition;
if (count < 0)
count = 0;
data.SetCount(count);
list.SetVirtualCount(count);
}
App::App()
{
Title("Virtual ArrayCtrl");
Sizeable().Zoomable();
const Size sz(640, 480);
SetRect(sz); SetMinSize(sz);
btnAdd.SetLabel("Add") <<= THISBACK(OnAdd);
btnRemove.SetLabel("Remove") <<= THISBACK(OnRemove);
HeaderCtrl::Column& hc = list.AddRowNumColumn("Index").HeaderTab();
const int textWidth = GetTextSize(AsString(count), Draw::GetStdFont()).cx,
columnWidth = textWidth + hc.GetMargin() * 2 + 1;
hc.Fixed(columnWidth);
list.AddRowNumColumn("Data", 50).SetConvert(Single<NumberToText<GetIndexData> >());
list.AddRowNumColumn("Reverse Data", 50).SetConvert(Single<NumberToText<GetReverseData> >());
list.SetVirtualCount(count);
const int offset = 75;
Add(btnAdd.TopPosZ(4, 20).LeftPosZ(4, offset));
Add(btnRemove.TopPosZ(4, 20).LeftPosZ(offset + 8, offset));
Add(list.HSizePosZ(4, 4).VSizePosZ(28, 4));
}
GUI_APP_MAIN
{
Ctrl::GlobalBackPaint();
data.SetCount(count);
{
Progress p;
p.SetText("Preparing the data..");
for (int i = 0; i < count; ++i) {
data[i] = FormatData(i);
p.Set(i, count);
}
}
App app;
app.Run();
}

Where instead of Vector<String> you could use your "faster" container, filled by parallel, if you want. Or even try to show real time (or cached) results, calculated by some index, without using any container.
[Updated on: Thu, 25 April 2013 17:14] Report message to a moderator
|
|
|
|
Re: GridCtrl performance [message #39776 is a reply to message #39775] |
Thu, 25 April 2013 18:53   |
Sender Ghost
Messages: 301 Registered: November 2008
|
Senior Member |
|
|
crydev wrote on Thu, 25 April 2013 17:49 | However, I'm having trouble implementing my own data in it. Say I have the following data, how could this be properly implemented using the virtual ArrayCtrl?
template <class T>
struct MemData
{
int address; // column address
T value; // column value
};
|
Depends from the type of T. If T is String, then modified version of example application might look like follows:
Toggle Spoiler
#include <CtrlLib/CtrlLib.h>
using namespace Upp;
int count = 0x100000;
template <class T>
struct MemData : Moveable<MemData<T> >
{
int address; // column address
T value; // column value
};
typedef MemData<String> StringMemData;
Vector<StringMemData> data;
template <String (GetData) (int index)>
struct NumberToText : public Convert {
virtual Value Format(const Value& q) const {
return GetData(int(q));
}
};
String GetAddress(int index)
{
ASSERT(index >= 0 && index < data.GetCount());
return Format64Hex(data[index].address);
}
String GetIndexValue(int index)
{
ASSERT(index >= 0 && index < data.GetCount());
return data[index].value;
}
String GetReverseValue(int index)
{
ASSERT(index >= 0 && index < data.GetCount());
return data[count - index - 1].value;
}
StringMemData FormatData(int index)
{
StringMemData d;
d.address = index;
d.value = NFormat("Data #%d", index + 1);
return d;
}
class App : public TopWindow {
public:
typedef App CLASSNAME;
App();
// Ctrls
ArrayCtrl list;
Button btnAdd, btnRemove;
// Events
void OnAdd();
void OnRemove();
};
const int addition = count / 2;
void App::OnAdd()
{
const int prevCount = count;
count += addition;
data.SetCount(count);
for (int i = prevCount; i < count; ++i)
data[i] = FormatData(i);
list.SetVirtualCount(count);
}
void App::OnRemove()
{
count -= addition;
if (count < 0)
count = 0;
data.SetCount(count);
list.SetVirtualCount(count);
}
App::App()
{
Title("Virtual ArrayCtrl");
Sizeable().Zoomable();
const Size sz(640, 480);
SetRect(sz); SetMinSize(sz);
btnAdd.SetLabel("Add") <<= THISBACK(OnAdd);
btnRemove.SetLabel("Remove") <<= THISBACK(OnRemove);
list.AddRowNumColumn("Address", 12).SetConvert(Single<NumberToText<GetAddress> >());
list.AddRowNumColumn("Value", 44).SetConvert(Single<NumberToText<GetIndexValue> >());
list.AddRowNumColumn("Reverse Value", 44).SetConvert(Single<NumberToText<GetReverseValue> >());
list.SetVirtualCount(count);
const int offset = 75;
Add(btnAdd.TopPosZ(4, 20).LeftPosZ(4, offset));
Add(btnRemove.TopPosZ(4, 20).LeftPosZ(offset + 8, offset));
Add(list.HSizePosZ(4, 4).VSizePosZ(28, 4));
}
GUI_APP_MAIN
{
Ctrl::GlobalBackPaint();
data.SetCount(count);
{
Progress p;
p.SetText("Preparing the data..");
for (int i = 0; i < count; ++i) {
data[i] = FormatData(i);
p.Set(i, count);
}
}
App app;
app.Run();
}
If you need to use another types, then just change the function declaration of NumberToText template, but return compatible types for ArrayCtrl values (which is Value).
[Updated on: Thu, 25 April 2013 18:54] Report message to a moderator
|
|
|
|
Goto Forum:
Current Time: Tue Apr 29 15:04:57 CEST 2025
Total time taken to generate the page: 0.01101 seconds
|
|
|