Albrecht Schlosser wrote:
I'm just testing a new *optimized* implementation :-)
Results with 40,000 children (Fl_Buttons) in Fl_Scroll:
old implementation:
- Fl_Group::clear() about 1.9 - 2.0 sec.
- Fl_Scroll::clear() about 1.3 sec.
new implementation: about 0.03 - 0.05 sec !
This new implementation will also be used in Fl_Scroll::clear()
without a significant slowdown effect.
I just committed subversion release 7038 with the optimized
version of both Fl_Group::clear() and Fl_Scroll::clear().
FWIW: I'll also append my last version of the test/demo program
that shows the measured time for creating and deleting up to
100,000 buttons in/from an Fl_Scroll.
Figures: Windows XP, Pentium 4 (2.41 GHz), old vs. optimized:
100,000 buttons: 12.235 vs. 0.109 seconds.
50,000 buttons: 3.047 vs. 0.047 seconds.
10,000 buttons: 0.125 vs. 0.016 seconds.
Albrecht
//
// modified Fl_Scroll test program for the Fast Light Tool Kit (FLTK).
// version 2: dynamic loading of widgets
//
#include <FL/Fl.H>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Scroll.H>
#include <FL/Fl_Scrollbar.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Check_Button.H>
#include <FL/Fl_Value_Slider.H>
#include <FL/Fl_Output.H>
#include <FL/fl_ask.h>
#include <time.h>
#include <sys/timeb.h>
#include <stdio.h>
#include <string.h>
#include <stdio.h>
static char *ctime (double *secs)
{
static char tbuf[40];
struct timeb ctime;
struct tm *lt;
ftime (&ctime);
lt = localtime (&ctime.time);
sprintf (tbuf,"%2.2d:%2.2d:%2.2d.%3.3d",
lt->tm_hour,
lt->tm_min,
lt->tm_sec,
ctime.millitm);
if (secs) { // return seconds and milliseconds
*secs = (double)lt->tm_sec + ((double)ctime.millitm)/1000.0;
}
return tbuf;
}
Fl_Scroll* thescroll = 0;
Fl_Scrollbar* hsb = 0;
Fl_Scrollbar* vsb = 0;
Fl_Value_Slider *numb = 0;
Fl_Check_Button *cq = 0;
Fl_Output *dtime = 0;
double start, end, delta;
static void set_time() {
char buf[30];
delta = end - start;
if (delta<0) delta += 60.0;
sprintf (buf,"%5.3f sec.",delta);
dtime->value(buf);
printf ("--> delta time = %5.3f sec.\n",delta);
}
void reset_cb(Fl_Widget*, void* v) {
printf ("reset_cb: %s - started,
children=%6d\n",ctime(&start),thescroll->children());
int nw = (int)numb->value();
if (nw <1000 || nw > 100000) nw = 20000;
if (thescroll->children() > 2) {
fl_alert("You must clear the scroll group first");
return;
}
Fl_Group *curr = Fl_Group::current();
thescroll->begin();
int n = 0;
for (int y=0; y<(nw+99)/100; y++) for (int x=0; x<100; x++) {
char buf[20]; sprintf(buf,"%d",n++);
Fl_Button* b = new Fl_Button(x*60,y*20,60,20);
b->copy_label(buf);
b->color(n%128);
b->labelcolor(FL_WHITE);
if (n > nw) break;
}
Fl_Group::current(curr);
printf ("reset_cb: %s - finished,
children=%6d\n",ctime(&end),thescroll->children());
set_time();
}
void clear_cb(Fl_Widget*, void* v) {
int use_group = (int)v;
if (cq->value()) {
int i;
for (i=0; i<99; i++)
if (!Fl::readqueue()) break;
printf ("Fl::readqueue() - flushed %d entries\n",i);
}
if (use_group) {
printf ("using Fl_Group::clear()\n");
} else {
printf ("using Fl_Scroll::clear()\n");
}
printf ("clear_cb: %s - started,
children=%6d\n",ctime(&start),thescroll->children());
if (use_group) {
thescroll->remove(hsb);
thescroll->remove(vsb);
thescroll->Fl_Group::clear();
thescroll->add(hsb);
thescroll->add(vsb);
} else {
thescroll->clear();
}
printf ("clear_cb: %s - finished,
children=%6d\n",ctime(&end),thescroll->children());
set_time();
thescroll->redraw();
}
int main(int argc, char** argv) {
setvbuf (stdout,NULL,_IONBF,0); // stdout unbuffered
Fl_Window window(600,420);
Fl_Scroll scroll(0,0,600,300);
thescroll = &scroll; // save global vars
hsb = &thescroll->hscrollbar;
vsb = &thescroll->scrollbar;
scroll.end();
scroll.type(Fl_Scroll::BOTH);
window.resizable(scroll);
Fl_Button *clear0 = new Fl_Button (20,320,120,20,"Fl_Scroll::clear");
clear0->callback(clear_cb,(void*)0);
Fl_Button *clear1 = new Fl_Button (20,350,120,20,"Fl_Group::clear");
clear1->callback(clear_cb,(void*)1);
cq = new Fl_Check_Button (20,380,160,20,"clear Fl::readqueue");
cq->value(0);
dtime = new Fl_Output (200,350,80,20,"time:");
dtime->value("");
numb = new Fl_Value_Slider (380,320,200,25,"buttons:");
numb->minimum(1000);
numb->maximum(100000);
numb->step(100);
numb->labelsize(16);
numb->align(FL_ALIGN_LEFT);
numb->type(FL_HORIZONTAL);
numb->value(10000);
Fl_Button *res = new Fl_Button (380,350,200,20,"create buttons");
res->callback(reset_cb,(void*)0);
window.end();
// reset_cb(thescroll,(void*)0); // add the buttons
window.show(argc,argv);
return Fl::run();
}
_______________________________________________
fltk-dev mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-dev