Re: Insets Data Structure (was: Re: 20% speedup of paragraph redraw with simple patch)

2007-06-18 Thread Alfredo Braunstein
Dov Feldstern wrote:

 Why do we need that structure at all? Given that our char_type is
 32-bits, and we don't use all 32, we could do something like the
 following: the insets themselves could be stored in a hash table,
 without storing their positions in that structure. At each position in
 the paragraph where an inset appears, instead of just the META_INSET
 character, we store an actual key into the hash table. (From the comment
 on META_INSET I understand that we don't use any values above 0x20001
 --- which means that we have more than enough room for keys to as many
 insets as we'd like in a single paragraph...). Then, there's no need of
 keeping the insets structure in sync with the paragraph itself after
 every insertion...

Note that if anything, this will make faster insertion and deletions, not
lookups (the potential bottleneck that started this thread). I doubt that
it has a real impact.

Second point, I think a hash table is really not good because then iteration
*in order* over insets of a paragraph becomes much worse than now (I think
we use it in a few places).

Now for a change, how about focusing on real bottlenecks? SCNR ;-)

A/




Re: Insets Data Structure (was: Re: 20% speedup of paragraph redraw with simple patch)

2007-06-18 Thread Andre Poenitz
On Mon, Jun 18, 2007 at 10:41:54PM +0200, Alfredo Braunstein wrote:
 Dov Feldstern wrote:
 
  Why do we need that structure at all? Given that our char_type is
  32-bits, and we don't use all 32, we could do something like the
  following: the insets themselves could be stored in a hash table,
  without storing their positions in that structure. At each position in
  the paragraph where an inset appears, instead of just the META_INSET
  character, we store an actual key into the hash table. (From the comment
  on META_INSET I understand that we don't use any values above 0x20001
  --- which means that we have more than enough room for keys to as many
  insets as we'd like in a single paragraph...). Then, there's no need of
  keeping the insets structure in sync with the paragraph itself after
  every insertion...
 
 Note that if anything, this will make faster insertion and deletions, not
 lookups (the potential bottleneck that started this thread). I doubt that
 it has a real impact.
 
 Second point, I think a hash table is really not good because then iteration
 *in order* over insets of a paragraph becomes much worse than now (I think
 we use it in a few places).
 
 Now for a change, how about focusing on real bottlenecks? SCNR ;-)

Like the build process? ;-}

Andre'


Re: Insets Data Structure (was: Re: 20% speedup of paragraph redraw with simple patch)

2007-06-18 Thread Alfredo Braunstein
Dov Feldstern wrote:

> Why do we need that structure at all? Given that our char_type is
> 32-bits, and we don't use all 32, we could do something like the
> following: the insets themselves could be stored in a hash table,
> without storing their positions in that structure. At each position in
> the paragraph where an inset appears, instead of just the META_INSET
> character, we store an actual key into the hash table. (From the comment
> on META_INSET I understand that we don't use any values above 0x20001
> --- which means that we have more than enough room for keys to as many
> insets as we'd like in a single paragraph...). Then, there's no need of
> keeping the insets structure in sync with the paragraph itself after
> every insertion...

Note that if anything, this will make faster insertion and deletions, not
lookups (the potential bottleneck that started this thread). I doubt that
it has a real impact.

Second point, I think a hash table is really not good because then iteration
*in order* over insets of a paragraph becomes much worse than now (I think
we use it in a few places).

Now for a change, how about focusing on real bottlenecks? SCNR ;-)

A/




Re: Insets Data Structure (was: Re: 20% speedup of paragraph redraw with simple patch)

2007-06-18 Thread Andre Poenitz
On Mon, Jun 18, 2007 at 10:41:54PM +0200, Alfredo Braunstein wrote:
> Dov Feldstern wrote:
> 
> > Why do we need that structure at all? Given that our char_type is
> > 32-bits, and we don't use all 32, we could do something like the
> > following: the insets themselves could be stored in a hash table,
> > without storing their positions in that structure. At each position in
> > the paragraph where an inset appears, instead of just the META_INSET
> > character, we store an actual key into the hash table. (From the comment
> > on META_INSET I understand that we don't use any values above 0x20001
> > --- which means that we have more than enough room for keys to as many
> > insets as we'd like in a single paragraph...). Then, there's no need of
> > keeping the insets structure in sync with the paragraph itself after
> > every insertion...
> 
> Note that if anything, this will make faster insertion and deletions, not
> lookups (the potential bottleneck that started this thread). I doubt that
> it has a real impact.
> 
> Second point, I think a hash table is really not good because then iteration
> *in order* over insets of a paragraph becomes much worse than now (I think
> we use it in a few places).
> 
> Now for a change, how about focusing on real bottlenecks? SCNR ;-)

Like the build process? ;-}

Andre'


Insets Data Structure (was: Re: 20% speedup of paragraph redraw with simple patch)

2007-06-17 Thread Dov Feldstern

Jean-Marc Lasgouttes wrote:

Dov == Dov Feldstern [EMAIL PROTECTED] writes:



Dov Hmm, I just came across this yesterday when trying to figure out
Dov what was going on with bug 3011, and wondered about it. I'm not
Dov sure if this is what you mean or not, but it might be relevant...

Dov 
http://www.lyx.org/trac/browser/lyx-devel/trunk/src/Paragraph.cpp?rev=18599#L446

Yes, what I mean is that in this case we would have to recreate the
structure instead of update it. I do not know how costly it is but
Abdel is confident that it is not a problem.

JMarc



Why do we need that structure at all? Given that our char_type is 
32-bits, and we don't use all 32, we could do something like the 
following: the insets themselves could be stored in a hash table, 
without storing their positions in that structure. At each position in 
the paragraph where an inset appears, instead of just the META_INSET 
character, we store an actual key into the hash table. (From the comment 
on META_INSET I understand that we don't use any values above 0x20001 
--- which means that we have more than enough room for keys to as many 
insets as we'd like in a single paragraph...). Then, there's no need of 
keeping the insets structure in sync with the paragraph itself after 
every insertion...




Insets Data Structure (was: Re: 20% speedup of paragraph redraw with simple patch)

2007-06-17 Thread Dov Feldstern

Jean-Marc Lasgouttes wrote:

"Dov" == Dov Feldstern <[EMAIL PROTECTED]> writes:



Dov> Hmm, I just came across this yesterday when trying to figure out
Dov> what was going on with bug 3011, and wondered about it. I'm not
Dov> sure if this is what you mean or not, but it might be relevant...

Dov> 
http://www.lyx.org/trac/browser/lyx-devel/trunk/src/Paragraph.cpp?rev=18599#L446

Yes, what I mean is that in this case we would have to recreate the
structure instead of update it. I do not know how costly it is but
Abdel is confident that it is not a problem.

JMarc



Why do we need that structure at all? Given that our char_type is 
32-bits, and we don't use all 32, we could do something like the 
following: the insets themselves could be stored in a hash table, 
without storing their positions in that structure. At each position in 
the paragraph where an inset appears, instead of just the META_INSET 
character, we store an actual key into the hash table. (From the comment 
on META_INSET I understand that we don't use any values above 0x20001 
--- which means that we have more than enough room for keys to as many 
insets as we'd like in a single paragraph...). Then, there's no need of 
keeping the insets structure in sync with the paragraph itself after 
every insertion...




Re: 20% speedup of paragraph redraw with simple patch

2007-06-15 Thread Abdelrazak Younes

Andre Poenitz wrote:

On Thu, Jun 14, 2007 at 05:49:53PM +0200, Abdelrazak Younes wrote:

Moreover, it remains to be seen whether the map is faster in the cases
where the container typically has at most 10 elements. It might be
that a stupid plain loop is faster...

Maybe not faster but a lot cleaner.


You may have noticed that users are complaining about speed, not on code
cleanliness.


When you quote something please quote the full sentence:
Am I am pretty sure that it will make the cases similar to the one 
found by Stefan easier to optimize.


I end this thread.

Abdel.



Re: 20% speedup of paragraph redraw with simple patch

2007-06-15 Thread Martin Vermeer
On Thu, Jun 14, 2007 at 09:01:49PM +0200, Andre Poenitz wrote:
 On Thu, Jun 14, 2007 at 05:05:32PM +0200, Stefan Schimanski wrote:
  I did some profiling of paragraph drawing. 20% of the whole time  
  while inserting characters and redrawing the screen was taken by  
  Paragraph::getInset calls, each for every character. This is stupid.  
  See the patch below for a loop iterating over the insets of a  
  paragraph instead. O(insetnumber) instead of O(charnumber * ln  
  insetnumber).
  
  Stefan
  

...

 
 Good catch.  Patch is fine with me.
 
 [And I continue hating that wide() business ;-}]
 
 Andre'

Come and help rip it out from 1.6 in Bromarv... Abdel's idea is
sound and perhaps that's what I should have done in the first
place rather than this elaborate hack.

- Martin



Re: 20% speedup of paragraph redraw with simple patch

2007-06-15 Thread Jean-Marc Lasgouttes
 Dov == Dov Feldstern [EMAIL PROTECTED] writes:


Dov Hmm, I just came across this yesterday when trying to figure out
Dov what was going on with bug 3011, and wondered about it. I'm not
Dov sure if this is what you mean or not, but it might be relevant...

Dov 
http://www.lyx.org/trac/browser/lyx-devel/trunk/src/Paragraph.cpp?rev=18599#L446

Yes, what I mean is that in this case we would have to recreate the
structure instead of update it. I do not know how costly it is but
Abdel is confident that it is not a problem.

JMarc


Re: 20% speedup of paragraph redraw with simple patch

2007-06-15 Thread Abdelrazak Younes

Andre Poenitz wrote:

On Thu, Jun 14, 2007 at 05:49:53PM +0200, Abdelrazak Younes wrote:

Moreover, it remains to be seen whether the map is faster in the cases
where the container typically has at most 10 elements. It might be
that a stupid plain loop is faster...

Maybe not faster but a lot cleaner.


You may have noticed that users are complaining about speed, not on code
cleanliness.


When you quote something please quote the full sentence:
"Am I am pretty sure that it will make the cases similar to the one 
found by Stefan easier to optimize."


I end this thread.

Abdel.



Re: 20% speedup of paragraph redraw with simple patch

2007-06-15 Thread Martin Vermeer
On Thu, Jun 14, 2007 at 09:01:49PM +0200, Andre Poenitz wrote:
> On Thu, Jun 14, 2007 at 05:05:32PM +0200, Stefan Schimanski wrote:
> > I did some profiling of paragraph drawing. 20% of the whole time  
> > while inserting characters and redrawing the screen was taken by  
> > Paragraph::getInset calls, each for every character. This is stupid.  
> > See the patch below for a loop iterating over the insets of a  
> > paragraph instead. O(insetnumber) instead of O(charnumber * ln  
> > insetnumber).
> > 
> > Stefan
> > 

...

> 
> Good catch.  Patch is fine with me.
> 
> [And I continue hating that wide() business ;-}]
> 
> Andre'

Come and help rip it out from 1.6 in Bromarv... Abdel's idea is
sound and perhaps that's what I should have done in the first
place rather than this elaborate hack.

- Martin



Re: 20% speedup of paragraph redraw with simple patch

2007-06-15 Thread Jean-Marc Lasgouttes
> "Dov" == Dov Feldstern <[EMAIL PROTECTED]> writes:


Dov> Hmm, I just came across this yesterday when trying to figure out
Dov> what was going on with bug 3011, and wondered about it. I'm not
Dov> sure if this is what you mean or not, but it might be relevant...

Dov> 
http://www.lyx.org/trac/browser/lyx-devel/trunk/src/Paragraph.cpp?rev=18599#L446

Yes, what I mean is that in this case we would have to recreate the
structure instead of update it. I do not know how costly it is but
Abdel is confident that it is not a problem.

JMarc


20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Stefan Schimanski
I did some profiling of paragraph drawing. 20% of the whole time  
while inserting characters and redrawing the screen was taken by  
Paragraph::getInset calls, each for every character. This is stupid.  
See the patch below for a loop iterating over the insets of a  
paragraph instead. O(insetnumber) instead of O(charnumber * ln  
insetnumber).


Stefan

Index: src/rowpainter.cpp
===
--- src/rowpainter.cpp  (Revision 18765)
+++ src/rowpainter.cpp  (Arbeitskopie)
@@ -958,10 +958,11 @@
// done here.
 		// JSpitzm: We should aim at removing wide() altogether while  
retaining

// typing speed within insets.
-   for (pos_type i = rit-pos() ; i != rit-endpos(); ++i) {
-   Inset const * const in = par.getInset(i);
-   if (in) {
-   InsetText * t = const_castInsetText 
*(in-asTextInset());
+		InsetList::const_iterator iit = par.insetlist.insetIterator(rit- 
pos());

+   InsetList::const_iterator iend = par.insetlist.end();
+   for (; iit != iend  iit-pos  rit-endpos(); ++iit) {
+   if (iit-inset) {
+   InsetText * t = const_castInsetText 
*(iit-inset-asTextInset());
if (t)
t-setWide(in_inset_alone_on_row
leftEdgeFixed



parpaintinsetloop.patch
Description: Binary data


PGP.sig
Description: Signierter Teil der Nachricht


Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Jean-Marc Lasgouttes
 Stefan == Stefan Schimanski [EMAIL PROTECTED] writes:

Stefan I did some profiling of paragraph drawing. 20% of the whole
Stefan time while inserting characters and redrawing the screen was
Stefan taken by Paragraph::getInset calls, each for every character.
Stefan This is stupid. See the patch below for a loop iterating over
Stefan the insets of a paragraph instead. O(insetnumber) instead of
Stefan O(charnumber * ln insetnumber).

Very good catch. Did you find it with Shark.app? Profiling with tools
like gprof does not contain the cost of the actual painting and gives
too much importance to loops like above.

 Note also that the argument insetIterator(pos) probably has
a cost too, and that it is not needed IMO. Since one is iterating over
the whole paragraph, can't we keep the same InsetList::iterator all
the time?

It is nice to see how a drawing optimization makes the drawing slower...

JMarc



Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Stefan Schimanski


Am 14.06.2007 um 17:19 schrieb Jean-Marc Lasgouttes:


Stefan == Stefan Schimanski [EMAIL PROTECTED] writes:


Stefan I did some profiling of paragraph drawing. 20% of the whole
Stefan time while inserting characters and redrawing the screen was
Stefan taken by Paragraph::getInset calls, each for every character.
Stefan This is stupid. See the patch below for a loop iterating over
Stefan the insets of a paragraph instead. O(insetnumber) instead of
Stefan O(charnumber * ln insetnumber).

Very good catch. Did you find it with Shark.app? Profiling with tools
like gprof does not contain the cost of the actual painting and gives
too much importance to loops like above.


Yes, shark. And still on the way. I think there are still plenty of  
those things.



 Note also that the argument insetIterator(pos) probably has
a cost too, and that it is not needed IMO. Since one is iterating over
the whole paragraph, can't we keep the same InsetList::iterator all
the time?


Sure we can. But it does not show up in the profile currently. Note  
that it is only done once per line.


It is nice to see how a drawing optimization makes the drawing  
slower...


Didn't look what the loop is actually doing. Interesting if really  
have been meant like that.


Stefan


JMarc





PGP.sig
Description: Signierter Teil der Nachricht


Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Abdelrazak Younes

Stefan Schimanski wrote:
I did some profiling of paragraph drawing. 20% of the whole time while 
inserting characters and redrawing the screen was taken by 
Paragraph::getInset calls, each for every character.


The whole time? Including screen drawing?

This is stupid. See 
the patch below for a loop iterating over the insets of a paragraph 
instead. O(insetnumber) instead of O(charnumber * ln insetnumber).


I am OK with it but maybe the real problem is why getInset is so slow? 
Looking at InsetList::insetIterator(pos_type pos), this is no wonder really:


InsetList::iterator InsetList::insetIterator(pos_type pos)
{
InsetTable search_elem(pos, 0);
return lower_bound(list_.begin(), list_.end(), search_elem,
   InsetTablePosLess());
}

InsetTable is basically 'pairpos, Inset*', so this InsetList is 
basically reimplementing std::map in a less efficient way. Just 
replacing the 'vectorInsetTable' with a 'mappos, Inset*' will clean 
halves the code. And then you could just use the standard map iterator 
anywhere it makes sense; and I bet there is a lot of case were it make 
sense:



Find all getInset, Match case, Whole word, Subfolders, Find Results 1, 
lyx-trunk, *.c;*.cpp;*.cxx;*.cc;*.tli;*.tlh;*.h;*.hpp;*.hxx;*.hh
  D:\devel\lyx\trunk\src\CutAndPaste.cpp(195):			 
!pars[pit].insetAllowed(tmpbuf-getInset(i)-lyxCode()))
  D:\devel\lyx\trunk\src\DocIterator.cpp(72):	return 
paragraph().isInset(pos()) ? paragraph().getInset(pos()) : 0;
  D:\devel\lyx\trunk\src\DocIterator.cpp(89):	return 
paragraph().isInset(pos() - 1) ? paragraph().getInset(pos() - 1) : 0;
  D:\devel\lyx\trunk\src\DocIterator.cpp(106):	return 
paragraph().isInset(pos() - 1) ? paragraph().getInset(pos() - 1) : 0;
  D:\devel\lyx\trunk\src\DocIterator.cpp(331):n = 
paragraph().getInset(tip.pos());
  D:\devel\lyx\trunk\src\DocIterator.cpp(520):			n = 
paragraph().getInset(tip.pos());
  D:\devel\lyx\trunk\src\DocIterator.cpp(597):inset = 
cs.paragraph().getInset(cs.pos());
  D:\devel\lyx\trunk\src\output_plaintext.cpp(211):			int len = 
par.getInset(i)-plaintext(buf, os, rp);
  D:\devel\lyx\trunk\src\Paragraph.cpp(317):			 
owner_-getInset(pos)-setChange(change);
  D:\devel\lyx\trunk\src\Paragraph.cpp(334):	 
owner_-getInset(pos)-setChange(change);
  D:\devel\lyx\trunk\src\Paragraph.cpp(357): 
owner_-getInset(pos)-acceptChanges(bparams);
  D:\devel\lyx\trunk\src\Paragraph.cpp(366): 
owner_-getInset(pos)-acceptChanges(bparams);
  D:\devel\lyx\trunk\src\Paragraph.cpp(395): 
owner_-getInset(pos)-rejectChanges(bparams);
  D:\devel\lyx\trunk\src\Paragraph.cpp(681):		 
owner_-getInset(i)-plaintext(buf, os, runparams);
  D:\devel\lyx\trunk\src\Paragraph.cpp(690):		Inset * inset = 
owner_-getInset(i);
  D:\devel\lyx\trunk\src\Paragraph.cpp(1143):			Inset const * inset = 
getInset(i);
  D:\devel\lyx\trunk\src\Paragraph.cpp(2180):			Inset const * inset = 
getInset(i);
  D:\devel\lyx\trunk\src\Paragraph.cpp(2205):			Inset const * inset = 
getInset(i);
  D:\devel\lyx\trunk\src\Paragraph.cpp(2223):			Inset const * inset = 
getInset(i);
  D:\devel\lyx\trunk\src\Paragraph.cpp(2284):			Inset const * inset = 
getInset(i);
  D:\devel\lyx\trunk\src\Paragraph.cpp(2311):		 
getInset(pos)-lyxCode() == Inset::NEWLINE_CODE;
  D:\devel\lyx\trunk\src\Paragraph.cpp(2319):		|| (c == 
Paragraph::META_INSET  getInset(pos) 
  D:\devel\lyx\trunk\src\Paragraph.cpp(2320):	 
getInset(pos)-isLineSeparator());
  D:\devel\lyx\trunk\src\Paragraph.cpp(2328):		return 
getInset(pos)-isLetter();
  D:\devel\lyx\trunk\src\Paragraph.cpp(2408):		 
getInset(i)-textString(buffer, os);
  D:\devel\lyx\trunk\src\Paragraph.h(71):		/// try getInset() and 
crash. We should fix

  D:\devel\lyx\trunk\src\Paragraph.h(314):  Inset * getInset(pos_type pos) {
  D:\devel\lyx\trunk\src\Paragraph.h(318):	Inset const * 
getInset(pos_type pos) const {
  D:\devel\lyx\trunk\src\Paragraph.h(325):		
getInset(pos)-lyxCode() == Inset::HFILL_CODE;
  D:\devel\lyx\trunk\src\paragraph_funcs.cpp(40):		if 
(fromPar.getInset(fromPos)) {
  D:\devel\lyx\trunk\src\rowpainter.cpp(182):	Inset const * inset = 
par_.getInset(pos);
  D:\devel\lyx\trunk\src\rowpainter.cpp(422):		 
par_.getInset(pos)-descent());
  D:\devel\lyx\trunk\src\rowpainter.cpp(787):			 
isHighlyEditableInset(par_.getInset(pos));
  D:\devel\lyx\trunk\src\rowpainter.cpp(962):			Inset const * const in 
= par.getInset(i);

  D:\devel\lyx\trunk\src\Text.cpp(385): return 
par.getInset(pos)-width();
  D:\devel\lyx\trunk\src\Text.cpp(566):		 
par.getInset(pos)-display())
  D:\devel\lyx\trunk\src\Text2.cpp(315):		 
pars_[pit].getInset(pos)-noFontChange());
  D:\devel\lyx\trunk\src\Text2.cpp(317):	Inset * const inset = 
pars_[pit].getInset(pos);
  D:\devel\lyx\trunk\src\Text2.cpp(516):			 
pars_[pit].getInset(pos)-noFontChange())
  D:\devel\lyx\trunk\src\Text2.cpp(927):	Inset * insetBefore = pos? 
pars_[pit].getInset(pos - 1): 0;
  D:\devel\lyx\trunk\src\Text2.cpp(928):	//Inset * 

Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Stefan Schimanski


Am 14.06.2007 um 17:27 schrieb Abdelrazak Younes:


Stefan Schimanski wrote:
I did some profiling of paragraph drawing. 20% of the whole time  
while inserting characters and redrawing the screen was taken by  
Paragraph::getInset calls, each for every character.


The whole time? Including screen drawing?


Yes, including everything. But using stdlib-debug I have to admit.  
Compiling now without. I guess it is less problematic then.


This is stupid. See the patch below for a loop iterating over the  
insets of a paragraph instead. O(insetnumber) instead of O 
(charnumber * ln insetnumber).


I am OK with it but maybe the real problem is why getInset is so  
slow? Looking at InsetList::insetIterator(pos_type pos), this is no  
wonder really:


InsetList::iterator InsetList::insetIterator(pos_type pos)
{
InsetTable search_elem(pos, 0);
return lower_bound(list_.begin(), list_.end(), search_elem,
   InsetTablePosLess());
}

InsetTable is basically 'pairpos, Inset*', so this InsetList is  
basically reimplementing std::map in a less efficient way. Just  
replacing the 'vectorInsetTable' with a 'mappos, Inset*' will  
clean halves the code. And then you could just use the standard map  
iterator anywhere it makes sense; and I bet there is a lot of case  
were it make sense:





mapinsetlist.patch
Description: Binary data


Stefan

PGP.sig
Description: Signierter Teil der Nachricht


Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Abdelrazak Younes

Stefan Schimanski wrote:


Am 14.06.2007 um 17:27 schrieb Abdelrazak Younes:


Stefan Schimanski wrote:
I did some profiling of paragraph drawing. 20% of the whole time 
while inserting characters and redrawing the screen was taken by 
Paragraph::getInset calls, each for every character.


The whole time? Including screen drawing?


Yes, including everything. But using stdlib-debug I have to admit. 
Compiling now without. I guess it is less problematic then.


I am pretty sure it won't be that problematic then... too bad! ;-)

Abdel.



Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Alfredo Braunstein
Abdelrazak Younes wrote:

 I am OK with it but maybe the real problem is why getInset is so slow?
 Looking at InsetList::insetIterator(pos_type pos), this is no wonder
 really:
 
 InsetList::iterator InsetList::insetIterator(pos_type pos)
 {
 InsetTable search_elem(pos, 0);
 return lower_bound(list_.begin(), list_.end(), search_elem,
 InsetTablePosLess());
 }
 
 InsetTable is basically 'pairpos, Inset*', so this InsetList is
 basically reimplementing std::map in a less efficient way. Just

Are you sure it's less efficient? AFAICS this is O(ln n) just like std::map,
constants may vary (in one side or the other). 

 replacing the 'vectorInsetTable' with a 'mappos, Inset*' will clean
 halves the code. And then you could just use the standard map iterator
 anywhere it makes sense; and I bet there is a lot of case were it make
 sense:

The code will be a bit cleaner maybe... but it is self-contained and clean
enough, and has been working flawlessly for ages... so be sure there is
really a gain if you are going to switch.

A/




Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Jean-Marc Lasgouttes
 Stefan == Stefan Schimanski [EMAIL PROTECTED] writes:


Stefan Yes, including everything. But using stdlib-debug I have to
Stefan admit. Compiling now without. I guess it is less problematic
Stefan then.

Or maybe not problematic at all. stdlib is really very costly in terms
of iterating over stl constructs. Profiling with it is kind of useless...

 InsetTable is basically 'pair', so this InsetList is basically
 reimplementing std::map in a less efficient way. Just replacing the
 'vectorInsetTable' with a 'map' will clean halves the code. And
 then you could just use the standard map iterator anywhere it makes
 sense; and I bet there is a lot of case were it make sense:

But this is not for now, right?

Moreover, it remains to be seen whether the map is faster in the cases
where the container typically has at most 10 elements. It might be
that a stupid plain loop is faster...

JMarc


Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Abdelrazak Younes

Jean-Marc Lasgouttes wrote:

Stefan == Stefan Schimanski [EMAIL PROTECTED] writes:



Stefan Yes, including everything. But using stdlib-debug I have to
Stefan admit. Compiling now without. I guess it is less problematic
Stefan then.

Or maybe not problematic at all. stdlib is really very costly in terms
of iterating over stl constructs. Profiling with it is kind of useless...


InsetTable is basically 'pair', so this InsetList is basically
reimplementing std::map in a less efficient way. Just replacing the
'vectorInsetTable' with a 'map' will clean halves the code. And
then you could just use the standard map iterator anywhere it makes
sense; and I bet there is a lot of case were it make sense:


But this is not for now, right?


Right.



Moreover, it remains to be seen whether the map is faster in the cases
where the container typically has at most 10 elements. It might be
that a stupid plain loop is faster...


Maybe not faster but a lot cleaner. Am I am pretty sure that it will 
make the cases similar to the one found by Stefan easier to optimize.


Abdel.



Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Abdelrazak Younes

Alfredo Braunstein wrote:

Abdelrazak Younes wrote:


I am OK with it but maybe the real problem is why getInset is so slow?
Looking at InsetList::insetIterator(pos_type pos), this is no wonder
really:

InsetList::iterator InsetList::insetIterator(pos_type pos)
{
InsetTable search_elem(pos, 0);
return lower_bound(list_.begin(), list_.end(), search_elem,
InsetTablePosLess());
}

InsetTable is basically 'pairpos, Inset*', so this InsetList is
basically reimplementing std::map in a less efficient way. Just


Are you sure it's less efficient?


No, that was just a guess.


AFAICS this is O(ln n) just like std::map,
constants may vary (in one side or the other). 


replacing the 'vectorInsetTable' with a 'mappos, Inset*' will clean
halves the code. And then you could just use the standard map iterator
anywhere it makes sense; and I bet there is a lot of case were it make
sense:


The code will be a bit cleaner maybe...


For sure ;-)


but it is self-contained and clean
enough, and has been working flawlessly for ages... so be sure there is
really a gain if you are going to switch.


I am not proposing to switch before 1.5.0 but I might implement it just 
for fun and ask Stefan to try it out with Shark ;-)


Abdel.



Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Abdelrazak Younes

Abdelrazak Younes wrote:

Alfredo Braunstein wrote:



but it is self-contained and clean
enough, and has been working flawlessly for ages... so be sure there is
really a gain if you are going to switch.


I am not proposing to switch before 1.5.0 but I might implement it just 
for fun and ask Stefan to try it out with Shark ;-)


Just for fun Stefan, could you try this out?

Abdel.
Index: InsetList.cpp
===
--- InsetList.cpp   (revision 18766)
+++ InsetList.cpp   (working copy)
@@ -24,25 +24,7 @@
 namespace lyx {
 
 using std::endl;
-using std::lower_bound;
 
-
-namespace {
-
-typedef InsetList::InsetTable Table;
-
-class InsetTablePosLess : public std::binary_functionTable, Table, bool {
-public:
-   bool operator()(Table const  t1, Table const  t2) const
-   {
-   return t1.pos  t2.pos;
-   }
-};
-
-} // namespace anon
-
-
-
 InsetList::~InsetList()
 {
// If we begin storing a shared_ptr in the List
@@ -50,46 +32,39 @@
List::iterator it = list_.begin();
List::iterator end = list_.end();
for (; it != end; ++it) {
-   delete it-inset;
+   delete it-second;
}
 }
 
 
 InsetList::iterator InsetList::insetIterator(pos_type pos)
 {
-   InsetTable search_elem(pos, 0);
-   return lower_bound(list_.begin(), list_.end(), search_elem,
-  InsetTablePosLess());
+   return list_.find(pos);
 }
 
 
 InsetList::const_iterator InsetList::insetIterator(pos_type pos) const
 {
-   InsetTable search_elem(pos, 0);
-   return lower_bound(list_.begin(), list_.end(), search_elem,
-  InsetTablePosLess());
+   return list_.find(pos);
 }
 
 
 void InsetList::insert(Inset * inset, pos_type pos)
 {
-   List::iterator end = list_.end();
-   List::iterator it = insetIterator(pos);
-   if (it != end  it-pos == pos) {
+   List::iterator it = list_.find(pos);
+   if (it != list_.end())
lyxerr  ERROR (InsetList::insert): 
There is an inset in position:   pos  endl;
-   } else {
-   list_.insert(it, InsetTable(pos, inset));
-   }
+   else
+   list_[pos] = inset;;
 }
 
 
 void InsetList::erase(pos_type pos)
 {
-   List::iterator end = list_.end();
-   List::iterator it = insetIterator(pos);
-   if (it != end  it-pos == pos) {
-   delete it-inset;
+   List::iterator it = list_.find(pos);
+   if (it != list_.end()) {
+   delete it-second;
list_.erase(it);
}
 }
@@ -97,11 +72,10 @@
 
 Inset * InsetList::release(pos_type pos)
 {
-   List::iterator end = list_.end();
-   List::iterator it = insetIterator(pos);
-   if (it != end  it-pos == pos) {
-   Inset * tmp = it-inset;
-   it-inset = 0;
+   List::iterator it = list_.find(pos);
+   if (it != list_.end()) {
+   Inset * tmp = it-second;
+   it-second = 0;
return tmp;
}
return 0;
@@ -110,31 +84,32 @@
 
 Inset * InsetList::get(pos_type pos) const
 {
-   List::const_iterator end = list_.end();
-   List::const_iterator it = insetIterator(pos);
-   if (it != end  it-pos == pos)
-   return it-inset;
+   List::const_iterator it = list_.find(pos);
+   if (it != list_.end())
+   return it-second;
return 0;
 }
 
 
 void InsetList::increasePosAfterPos(pos_type pos)
 {
-   List::iterator end = list_.end();
-   List::iterator it = insetIterator(pos);
-   for (; it != end; ++it) {
-   ++it-pos;
-   }
+   List oldlist = list_;
+   list_.clear();
+   List::iterator end = oldlist.end();
+   List::iterator it = oldlist.find(pos);
+   for (; it != end; ++it)
+   list_[it-first + 1] = it-second;
 }
 
 
 void InsetList::decreasePosAfterPos(pos_type pos)
 {
-   List::iterator end = list_.end();
-   List::iterator it = insetIterator(pos);
-   for (; it != end; ++it) {
-   --it-pos;
-   }
+   List oldlist = list_;
+   list_.clear();
+   List::iterator end = oldlist.end();
+   List::iterator it = oldlist.find(pos);
+   for (; it != end; ++it)
+   list_[it-first - 1] = it-second;
 }
 
 
Index: InsetList.h
===
--- InsetList.h (revision 18766)
+++ InsetList.h (working copy)
@@ -14,7 +14,7 @@
 
 #include support/types.h
 
-#include vector
+#include map
 
 
 namespace lyx {
@@ -27,18 +27,8 @@
 class InsetList {
 public:
///
-   class InsetTable {
-   public:
-   ///
-   InsetTable(pos_type p, Inset * i) : pos(p), inset(i) {}
-   ///
-   pos_type pos;
-   ///
-   Inset * inset;
-   };
+   typedef std::mappos_type, 

Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Stefan Schimanski
Seems to be false alarm. getInset does not show up very much anymore  
without stdlib-debug. But there are still some interesting facts:


38% QPainter::drawText.
16% drawing of empty inline math insets (around every 20th character  
in the text)

16% for metrics calculation

I think the only way to really reduce the amount to draw is to switch  
to line based redrawing or even finer and relative coordinates for  
scrolling.


Stefan


Alfredo Braunstein wrote:

Abdelrazak Younes wrote:
I am OK with it but maybe the real problem is why getInset is so  
slow?

Looking at InsetList::insetIterator(pos_type pos), this is no wonder
really:

InsetList::iterator InsetList::insetIterator(pos_type pos)
{
InsetTable search_elem(pos, 0);
return lower_bound(list_.begin(), list_.end(), search_elem,
InsetTablePosLess());
}

InsetTable is basically 'pairpos, Inset*', so this InsetList is
basically reimplementing std::map in a less efficient way. Just

Are you sure it's less efficient?


No, that was just a guess.


AFAICS this is O(ln n) just like std::map,
constants may vary (in one side or the other).
replacing the 'vectorInsetTable' with a 'mappos, Inset*' will  
clean
halves the code. And then you could just use the standard map  
iterator
anywhere it makes sense; and I bet there is a lot of case were it  
make

sense:

The code will be a bit cleaner maybe...


For sure ;-)


but it is self-contained and clean
enough, and has been working flawlessly for ages... so be sure  
there is

really a gain if you are going to switch.


I am not proposing to switch before 1.5.0 but I might implement it  
just for fun and ask Stefan to try it out with Shark ;-)


Abdel.





PGP.sig
Description: Signierter Teil der Nachricht


Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Abdelrazak Younes

Abdelrazak Younes wrote:

Abdelrazak Younes wrote:

Alfredo Braunstein wrote:



but it is self-contained and clean
enough, and has been working flawlessly for ages... so be sure there is
really a gain if you are going to switch.


I am not proposing to switch before 1.5.0 but I might implement it 
just for fun and ask Stefan to try it out with Shark ;-)


Just for fun Stefan, could you try this out?


Forget about it, it won't compile because of the multitude of -pos and 
-inset access.


Abdel.



Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Stefan Schimanski

Abdelrazak Younes wrote:

Alfredo Braunstein wrote:



but it is self-contained and clean
enough, and has been working flawlessly for ages... so be sure  
there is

really a gain if you are going to switch.
I am not proposing to switch before 1.5.0 but I might implement it  
just for fun and ask Stefan to try it out with Shark ;-)


Just for fun Stefan, could you try this out?



You saw my patch to your first reply? I includes nearly the same  
patch. But without stdlib-debug there is no problem at all with all  
that.


Stefan


PGP.sig
Description: Signierter Teil der Nachricht


Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Jean-Marc Lasgouttes
 Abdelrazak == Abdelrazak Younes [EMAIL PROTECTED] writes:

Abdelrazak Maybe not faster but a lot cleaner. Am I am pretty sure
Abdelrazak that it will make the cases similar to the one found by
Abdelrazak Stefan easier to optimize.

Agreed.

Second thought: what is the first term of the map? If it is the
position, does this means that the map shall be recreated at each insertion?

JMarc


Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Jean-Marc Lasgouttes
 Stefan == Stefan Schimanski [EMAIL PROTECTED] writes:

Stefan Seems to be false alarm. getInset does not show up very much
Stefan anymore without stdlib-debug. But there are still some
Stefan interesting facts:

Stefan 38% QPainter::drawText. 

Looks more like what I would expect.

Stefan 16% drawing of empty inline math insets (around every 20th
Stefan character in the text) 

What do you mean?

Stefan 16% for metrics calculation

JMarc


Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Abdelrazak Younes

Stefan Schimanski wrote:

Abdelrazak Younes wrote:

Alfredo Braunstein wrote:



but it is self-contained and clean
enough, and has been working flawlessly for ages... so be sure there is
really a gain if you are going to switch.
I am not proposing to switch before 1.5.0 but I might implement it 
just for fun and ask Stefan to try it out with Shark ;-)


Just for fun Stefan, could you try this out?



You saw my patch to your first reply? I includes nearly the same patch. 
But without stdlib-debug there is no problem at all with all that.


OK.

Abdel.



Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Abdelrazak Younes

Stefan Schimanski wrote:
Seems to be false alarm. getInset does not show up very much anymore 
without stdlib-debug. But there are still some interesting facts:


38% QPainter::drawText.


This was expected on Mac. Still, IIRC the number is lower than what 
Bennett used to report a while ago. It shows that Qt4.3 is much better 
at drawing on Mac than previous version. Hopefully this number will keep 
decreasing with further release.



16% drawing of empty inline math insets (around every 20th character in 
the text)


What is that?


16% for metrics calculation


Calculation or hash table lookup?



I think the only way to really reduce the amount to draw is to switch to 
line based redrawing or even finer and relative coordinates for scrolling.


Once we re-organize the background painting in rowpainter (thus getting 
rid of wide() etc) I believe we will see a nice speedup because only the 
current line will have to be redrawn in all cases (within Inset or not).


Abdel.



Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Abdelrazak Younes

Jean-Marc Lasgouttes wrote:

Abdelrazak == Abdelrazak Younes [EMAIL PROTECTED] writes:


Abdelrazak Maybe not faster but a lot cleaner. Am I am pretty sure
Abdelrazak that it will make the cases similar to the one found by
Abdelrazak Stefan easier to optimize.

Agreed.

Second thought: what is the first term of the map?


In my first implementation the position. The atavantage is that then the 
Inset are ordered by position in memory and the code relies on that I 
think (but I am not sure). But the disavantage is:



If it is the
position, does this means that the map shall be recreated at each insertion?


Right but I reckon this is not very costly, because we do something 
similar in the Paragraph list when inserting or deleting a paragraph.


Abdel.



Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Stefan Schimanski


Am 14.06.2007 um 18:44 schrieb Abdelrazak Younes:


Stefan Schimanski wrote:
Seems to be false alarm. getInset does not show up very much  
anymore without stdlib-debug. But there are still some interesting  
facts:

38% QPainter::drawText.


This was expected on Mac. Still, IIRC the number is lower than what  
Bennett used to report a while ago. It shows that Qt4.3 is much  
better at drawing on Mac than previous version. Hopefully this  
number will keep decreasing with further release.



16% drawing of empty inline math insets (around every 20th  
character in the text)



What is that?


Basically the InsetMathHull::draw call with everything which follows.  
So at the end some QLPainter::line calls which turn out to be quite  
expensive IMO.



16% for metrics calculation


Calculation or hash table lookup?


The whole updateMetrics call, everything there summed up.

I think the only way to really reduce the amount to draw is to  
switch to line based redrawing or even finer and relative  
coordinates for scrolling.


Once we re-organize the background painting in rowpainter (thus  
getting rid of wide() etc) I believe we will see a nice speedup  
because only the current line will have to be redrawn in all cases  
(within Inset or not).


That sounds good.

Stefan


PGP.sig
Description: Signierter Teil der Nachricht


Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Andre Poenitz
On Thu, Jun 14, 2007 at 05:05:32PM +0200, Stefan Schimanski wrote:
 I did some profiling of paragraph drawing. 20% of the whole time  
 while inserting characters and redrawing the screen was taken by  
 Paragraph::getInset calls, each for every character. This is stupid.  
 See the patch below for a loop iterating over the insets of a  
 paragraph instead. O(insetnumber) instead of O(charnumber * ln  
 insetnumber).
 
 Stefan
 
 Index: src/rowpainter.cpp
 ===
 --- src/rowpainter.cpp(Revision 18765)
 +++ src/rowpainter.cpp(Arbeitskopie)
 @@ -958,10 +958,11 @@
   // done here.
   // JSpitzm: We should aim at removing wide() altogether 
   while  retaining
   // typing speed within insets.
 - for (pos_type i = rit-pos() ; i != rit-endpos(); ++i) {
 - Inset const * const in = par.getInset(i);
 - if (in) {
 - InsetText * t = const_castInsetText 
 *(in-asTextInset());
 + InsetList::const_iterator iit = 
 par.insetlist.insetIterator(rit-pos());
 + InsetList::const_iterator iend = par.insetlist.end();
 + for (; iit != iend  iit-pos  rit-endpos(); ++iit) {
 + if (iit-inset) {
 + InsetText * t = const_castInsetText 
 *(iit-inset-asTextInset());
   if (t)
   t-setWide(in_inset_alone_on_row
   leftEdgeFixed


Good catch.  Patch is fine with me.

[And I continue hating that wide() business ;-}]

Andre'



Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Dov Feldstern

Jean-Marc Lasgouttes wrote:

Abdelrazak == Abdelrazak Younes [EMAIL PROTECTED] writes:


Abdelrazak Maybe not faster but a lot cleaner. Am I am pretty sure
Abdelrazak that it will make the cases similar to the one found by
Abdelrazak Stefan easier to optimize.

Agreed.

Second thought: what is the first term of the map? If it is the
position, does this means that the map shall be recreated at each insertion?

JMarc



Hmm, I just came across this yesterday when trying to figure out what 
was going on with bug 3011, and wondered about it. I'm not sure if this 
is what you mean or not, but it might be relevant...


http://www.lyx.org/trac/browser/lyx-devel/trunk/src/Paragraph.cpp?rev=18599#L446



Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Andre Poenitz
On Thu, Jun 14, 2007 at 05:40:12PM +0200, Alfredo Braunstein wrote:
 Abdelrazak Younes wrote:
 
  I am OK with it but maybe the real problem is why getInset is so slow?
  Looking at InsetList::insetIterator(pos_type pos), this is no wonder
  really:
  
  InsetList::iterator InsetList::insetIterator(pos_type pos)
  {
  InsetTable search_elem(pos, 0);
  return lower_bound(list_.begin(), list_.end(), search_elem,
  InsetTablePosLess());
  }
  
  InsetTable is basically 'pairpos, Inset*', so this InsetList is
  basically reimplementing std::map in a less efficient way.

How do you [Abdel] arrive at the conclusion 'less efficient'?

 Are you sure it's less efficient? AFAICS this is O(ln n) just like std::map,
 constants may vary (in one side or the other). 

A sorted vector filled should be cheaper than a map in any case.

  replacing the 'vectorInsetTable' with a 'mappos, Inset*' will clean
  halves the code. And then you could just use the standard map iterator
  anywhere it makes sense; and I bet there is a lot of case were it make
  sense:
 
 The code will be a bit cleaner maybe... but it is self-contained and clean
 enough, and has been working flawlessly for ages... so be sure there is
 really a gain if you are going to switch.

Right.

Andre'


Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Andre Poenitz
On Thu, Jun 14, 2007 at 05:49:53PM +0200, Abdelrazak Younes wrote:
 Moreover, it remains to be seen whether the map is faster in the cases
 where the container typically has at most 10 elements. It might be
 that a stupid plain loop is faster...
 
 Maybe not faster but a lot cleaner.

You may have noticed that users are complaining about speed, not on code
cleanliness.

Andre'


20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Stefan Schimanski
I did some profiling of paragraph drawing. 20% of the whole time  
while inserting characters and redrawing the screen was taken by  
Paragraph::getInset calls, each for every character. This is stupid.  
See the patch below for a loop iterating over the insets of a  
paragraph instead. O(insetnumber) instead of O(charnumber * ln  
insetnumber).


Stefan

Index: src/rowpainter.cpp
===
--- src/rowpainter.cpp  (Revision 18765)
+++ src/rowpainter.cpp  (Arbeitskopie)
@@ -958,10 +958,11 @@
// done here.
 		// JSpitzm: We should aim at removing wide() altogether while  
retaining

// typing speed within insets.
-   for (pos_type i = rit->pos() ; i != rit->endpos(); ++i) {
-   Inset const * const in = par.getInset(i);
-   if (in) {
-   InsetText * t = const_cast(in->asTextInset());
+		InsetList::const_iterator iit = par.insetlist.insetIterator(rit- 
>pos());

+   InsetList::const_iterator iend = par.insetlist.end();
+   for (; iit != iend && iit->pos < rit->endpos(); ++iit) {
+   if (iit->inset) {
+   InsetText * t = const_cast(iit->inset->asTextInset());
if (t)
t->setWide(in_inset_alone_on_row
   && leftEdgeFixed



parpaintinsetloop.patch
Description: Binary data


PGP.sig
Description: Signierter Teil der Nachricht


Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Jean-Marc Lasgouttes
> "Stefan" == Stefan Schimanski <[EMAIL PROTECTED]> writes:

Stefan> I did some profiling of paragraph drawing. 20% of the whole
Stefan> time while inserting characters and redrawing the screen was
Stefan> taken by Paragraph::getInset calls, each for every character.
Stefan> This is stupid. See the patch below for a loop iterating over
Stefan> the insets of a paragraph instead. O(insetnumber) instead of
Stefan> O(charnumber * ln insetnumber).

Very good catch. Did you find it with Shark.app? Profiling with tools
like gprof does not contain the cost of the actual painting and gives
too much importance to loops like above.

 Note also that the argument insetIterator(pos) probably has
a cost too, and that it is not needed IMO. Since one is iterating over
the whole paragraph, can't we keep the same InsetList::iterator all
the time?

It is nice to see how a drawing optimization makes the drawing slower...

JMarc



Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Stefan Schimanski


Am 14.06.2007 um 17:19 schrieb Jean-Marc Lasgouttes:


"Stefan" == Stefan Schimanski <[EMAIL PROTECTED]> writes:


Stefan> I did some profiling of paragraph drawing. 20% of the whole
Stefan> time while inserting characters and redrawing the screen was
Stefan> taken by Paragraph::getInset calls, each for every character.
Stefan> This is stupid. See the patch below for a loop iterating over
Stefan> the insets of a paragraph instead. O(insetnumber) instead of
Stefan> O(charnumber * ln insetnumber).

Very good catch. Did you find it with Shark.app? Profiling with tools
like gprof does not contain the cost of the actual painting and gives
too much importance to loops like above.


Yes, shark. And still on the way. I think there are still plenty of  
those things.



 Note also that the argument insetIterator(pos) probably has
a cost too, and that it is not needed IMO. Since one is iterating over
the whole paragraph, can't we keep the same InsetList::iterator all
the time?


Sure we can. But it does not show up in the profile currently. Note  
that it is only done once per line.


It is nice to see how a drawing optimization makes the drawing  
slower...


Didn't look what the loop is actually doing. Interesting if really  
have been meant like that.


Stefan


JMarc





PGP.sig
Description: Signierter Teil der Nachricht


Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Abdelrazak Younes

Stefan Schimanski wrote:
I did some profiling of paragraph drawing. 20% of the whole time while 
inserting characters and redrawing the screen was taken by 
Paragraph::getInset calls, each for every character.


The whole time? Including screen drawing?

This is stupid. See 
the patch below for a loop iterating over the insets of a paragraph 
instead. O(insetnumber) instead of O(charnumber * ln insetnumber).


I am OK with it but maybe the real problem is why getInset is so slow? 
Looking at InsetList::insetIterator(pos_type pos), this is no wonder really:


InsetList::iterator InsetList::insetIterator(pos_type pos)
{
InsetTable search_elem(pos, 0);
return lower_bound(list_.begin(), list_.end(), search_elem,
   InsetTablePosLess());
}

InsetTable is basically 'pair', so this InsetList is 
basically reimplementing std::map in a less efficient way. Just 
replacing the 'vector' with a 'map' will clean 
halves the code. And then you could just use the standard map iterator 
anywhere it makes sense; and I bet there is a lot of case were it make 
sense:



Find all "getInset", Match case, Whole word, Subfolders, Find Results 1, 
"lyx-trunk", "*.c;*.cpp;*.cxx;*.cc;*.tli;*.tlh;*.h;*.hpp;*.hxx;*.hh"
  D:\devel\lyx\trunk\src\CutAndPaste.cpp(195):			 
!pars[pit].insetAllowed(tmpbuf->getInset(i)->lyxCode()))
  D:\devel\lyx\trunk\src\DocIterator.cpp(72):	return 
paragraph().isInset(pos()) ? paragraph().getInset(pos()) : 0;
  D:\devel\lyx\trunk\src\DocIterator.cpp(89):	return 
paragraph().isInset(pos() - 1) ? paragraph().getInset(pos() - 1) : 0;
  D:\devel\lyx\trunk\src\DocIterator.cpp(106):	return 
paragraph().isInset(pos() - 1) ? paragraph().getInset(pos() - 1) : 0;
  D:\devel\lyx\trunk\src\DocIterator.cpp(331):n = 
paragraph().getInset(tip.pos());
  D:\devel\lyx\trunk\src\DocIterator.cpp(520):			n = 
paragraph().getInset(tip.pos());
  D:\devel\lyx\trunk\src\DocIterator.cpp(597):inset = 
cs.paragraph().getInset(cs.pos());
  D:\devel\lyx\trunk\src\output_plaintext.cpp(211):			int len = 
par.getInset(i)->plaintext(buf, os, rp);
  D:\devel\lyx\trunk\src\Paragraph.cpp(317):			 
owner_->getInset(pos)->setChange(change);
  D:\devel\lyx\trunk\src\Paragraph.cpp(334):	 
owner_->getInset(pos)->setChange(change);
  D:\devel\lyx\trunk\src\Paragraph.cpp(357): 
owner_->getInset(pos)->acceptChanges(bparams);
  D:\devel\lyx\trunk\src\Paragraph.cpp(366): 
owner_->getInset(pos)->acceptChanges(bparams);
  D:\devel\lyx\trunk\src\Paragraph.cpp(395): 
owner_->getInset(pos)->rejectChanges(bparams);
  D:\devel\lyx\trunk\src\Paragraph.cpp(681):		 
owner_->getInset(i)->plaintext(buf, os, runparams);
  D:\devel\lyx\trunk\src\Paragraph.cpp(690):		Inset * inset = 
owner_->getInset(i);
  D:\devel\lyx\trunk\src\Paragraph.cpp(1143):			Inset const * inset = 
getInset(i);
  D:\devel\lyx\trunk\src\Paragraph.cpp(2180):			Inset const * inset = 
getInset(i);
  D:\devel\lyx\trunk\src\Paragraph.cpp(2205):			Inset const * inset = 
getInset(i);
  D:\devel\lyx\trunk\src\Paragraph.cpp(2223):			Inset const * inset = 
getInset(i);
  D:\devel\lyx\trunk\src\Paragraph.cpp(2284):			Inset const * inset = 
getInset(i);
  D:\devel\lyx\trunk\src\Paragraph.cpp(2311):		&& 
getInset(pos)->lyxCode() == Inset::NEWLINE_CODE;
  D:\devel\lyx\trunk\src\Paragraph.cpp(2319):		|| (c == 
Paragraph::META_INSET && getInset(pos) &&
  D:\devel\lyx\trunk\src\Paragraph.cpp(2320):	 
getInset(pos)->isLineSeparator());
  D:\devel\lyx\trunk\src\Paragraph.cpp(2328):		return 
getInset(pos)->isLetter();
  D:\devel\lyx\trunk\src\Paragraph.cpp(2408):		 
getInset(i)->textString(buffer, os);
  D:\devel\lyx\trunk\src\Paragraph.h(71):		/// try getInset() and 
crash. We should fix

  D:\devel\lyx\trunk\src\Paragraph.h(314):  Inset * getInset(pos_type pos) {
  D:\devel\lyx\trunk\src\Paragraph.h(318):	Inset const * 
getInset(pos_type pos) const {
  D:\devel\lyx\trunk\src\Paragraph.h(325):		   && 
getInset(pos)->lyxCode() == Inset::HFILL_CODE;
  D:\devel\lyx\trunk\src\paragraph_funcs.cpp(40):		if 
(fromPar.getInset(fromPos)) {
  D:\devel\lyx\trunk\src\rowpainter.cpp(182):	Inset const * inset = 
par_.getInset(pos);
  D:\devel\lyx\trunk\src\rowpainter.cpp(422):		 
par_.getInset(pos)->descent());
  D:\devel\lyx\trunk\src\rowpainter.cpp(787):			&& 
isHighlyEditableInset(par_.getInset(pos));
  D:\devel\lyx\trunk\src\rowpainter.cpp(962):			Inset const * const in 
= par.getInset(i);

  D:\devel\lyx\trunk\src\Text.cpp(385): return 
par.getInset(pos)->width();
  D:\devel\lyx\trunk\src\Text.cpp(566):		&& 
par.getInset(pos)->display())
  D:\devel\lyx\trunk\src\Text2.cpp(315):		 
pars_[pit].getInset(pos)->noFontChange());
  D:\devel\lyx\trunk\src\Text2.cpp(317):	Inset * const inset = 
pars_[pit].getInset(pos);
  D:\devel\lyx\trunk\src\Text2.cpp(516):			 
pars_[pit].getInset(pos)->noFontChange())
  D:\devel\lyx\trunk\src\Text2.cpp(927):	Inset * insetBefore = pos? 
pars_[pit].getInset(pos - 1): 0;
  

Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Stefan Schimanski


Am 14.06.2007 um 17:27 schrieb Abdelrazak Younes:


Stefan Schimanski wrote:
I did some profiling of paragraph drawing. 20% of the whole time  
while inserting characters and redrawing the screen was taken by  
Paragraph::getInset calls, each for every character.


The whole time? Including screen drawing?


Yes, including everything. But using stdlib-debug I have to admit.  
Compiling now without. I guess it is less problematic then.


This is stupid. See the patch below for a loop iterating over the  
insets of a paragraph instead. O(insetnumber) instead of O 
(charnumber * ln insetnumber).


I am OK with it but maybe the real problem is why getInset is so  
slow? Looking at InsetList::insetIterator(pos_type pos), this is no  
wonder really:


InsetList::iterator InsetList::insetIterator(pos_type pos)
{
InsetTable search_elem(pos, 0);
return lower_bound(list_.begin(), list_.end(), search_elem,
   InsetTablePosLess());
}

InsetTable is basically 'pair', so this InsetList is  
basically reimplementing std::map in a less efficient way. Just  
replacing the 'vector' with a 'map' will  
clean halves the code. And then you could just use the standard map  
iterator anywhere it makes sense; and I bet there is a lot of case  
were it make sense:





mapinsetlist.patch
Description: Binary data


Stefan

PGP.sig
Description: Signierter Teil der Nachricht


Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Abdelrazak Younes

Stefan Schimanski wrote:


Am 14.06.2007 um 17:27 schrieb Abdelrazak Younes:


Stefan Schimanski wrote:
I did some profiling of paragraph drawing. 20% of the whole time 
while inserting characters and redrawing the screen was taken by 
Paragraph::getInset calls, each for every character.


The whole time? Including screen drawing?


Yes, including everything. But using stdlib-debug I have to admit. 
Compiling now without. I guess it is less problematic then.


I am pretty sure it won't be that problematic then... too bad! ;-)

Abdel.



Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Alfredo Braunstein
Abdelrazak Younes wrote:

> I am OK with it but maybe the real problem is why getInset is so slow?
> Looking at InsetList::insetIterator(pos_type pos), this is no wonder
> really:
> 
> InsetList::iterator InsetList::insetIterator(pos_type pos)
> {
> InsetTable search_elem(pos, 0);
> return lower_bound(list_.begin(), list_.end(), search_elem,
> InsetTablePosLess());
> }
> 
> InsetTable is basically 'pair', so this InsetList is
> basically reimplementing std::map in a less efficient way. Just

Are you sure it's less efficient? AFAICS this is O(ln n) just like std::map,
constants may vary (in one side or the other). 

> replacing the 'vector' with a 'map' will clean
> halves the code. And then you could just use the standard map iterator
> anywhere it makes sense; and I bet there is a lot of case were it make
> sense:

The code will be a bit cleaner maybe... but it is self-contained and clean
enough, and has been working flawlessly for ages... so be sure there is
really a gain if you are going to switch.

A/




Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Jean-Marc Lasgouttes
> "Stefan" == Stefan Schimanski <[EMAIL PROTECTED]> writes:


Stefan> Yes, including everything. But using stdlib-debug I have to
Stefan> admit. Compiling now without. I guess it is less problematic
Stefan> then.

Or maybe not problematic at all. stdlib is really very costly in terms
of iterating over stl constructs. Profiling with it is kind of useless...

>> InsetTable is basically 'pair', so this InsetList is basically
>> reimplementing std::map in a less efficient way. Just replacing the
>> 'vector' with a 'map' will clean halves the code. And
>> then you could just use the standard map iterator anywhere it makes
>> sense; and I bet there is a lot of case were it make sense:

But this is not for now, right?

Moreover, it remains to be seen whether the map is faster in the cases
where the container typically has at most 10 elements. It might be
that a stupid plain loop is faster...

JMarc


Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Abdelrazak Younes

Jean-Marc Lasgouttes wrote:

"Stefan" == Stefan Schimanski <[EMAIL PROTECTED]> writes:



Stefan> Yes, including everything. But using stdlib-debug I have to
Stefan> admit. Compiling now without. I guess it is less problematic
Stefan> then.

Or maybe not problematic at all. stdlib is really very costly in terms
of iterating over stl constructs. Profiling with it is kind of useless...


InsetTable is basically 'pair', so this InsetList is basically
reimplementing std::map in a less efficient way. Just replacing the
'vector' with a 'map' will clean halves the code. And
then you could just use the standard map iterator anywhere it makes
sense; and I bet there is a lot of case were it make sense:


But this is not for now, right?


Right.



Moreover, it remains to be seen whether the map is faster in the cases
where the container typically has at most 10 elements. It might be
that a stupid plain loop is faster...


Maybe not faster but a lot cleaner. Am I am pretty sure that it will 
make the cases similar to the one found by Stefan easier to optimize.


Abdel.



Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Abdelrazak Younes

Alfredo Braunstein wrote:

Abdelrazak Younes wrote:


I am OK with it but maybe the real problem is why getInset is so slow?
Looking at InsetList::insetIterator(pos_type pos), this is no wonder
really:

InsetList::iterator InsetList::insetIterator(pos_type pos)
{
InsetTable search_elem(pos, 0);
return lower_bound(list_.begin(), list_.end(), search_elem,
InsetTablePosLess());
}

InsetTable is basically 'pair', so this InsetList is
basically reimplementing std::map in a less efficient way. Just


Are you sure it's less efficient?


No, that was just a guess.


AFAICS this is O(ln n) just like std::map,
constants may vary (in one side or the other). 


replacing the 'vector' with a 'map' will clean
halves the code. And then you could just use the standard map iterator
anywhere it makes sense; and I bet there is a lot of case were it make
sense:


The code will be a bit cleaner maybe...


For sure ;-)


but it is self-contained and clean
enough, and has been working flawlessly for ages... so be sure there is
really a gain if you are going to switch.


I am not proposing to switch before 1.5.0 but I might implement it just 
for fun and ask Stefan to try it out with Shark ;-)


Abdel.



Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Abdelrazak Younes

Abdelrazak Younes wrote:

Alfredo Braunstein wrote:



but it is self-contained and clean
enough, and has been working flawlessly for ages... so be sure there is
really a gain if you are going to switch.


I am not proposing to switch before 1.5.0 but I might implement it just 
for fun and ask Stefan to try it out with Shark ;-)


Just for fun Stefan, could you try this out?

Abdel.
Index: InsetList.cpp
===
--- InsetList.cpp   (revision 18766)
+++ InsetList.cpp   (working copy)
@@ -24,25 +24,7 @@
 namespace lyx {
 
 using std::endl;
-using std::lower_bound;
 
-
-namespace {
-
-typedef InsetList::InsetTable Table;
-
-class InsetTablePosLess : public std::binary_function {
-public:
-   bool operator()(Table const & t1, Table const & t2) const
-   {
-   return t1.pos < t2.pos;
-   }
-};
-
-} // namespace anon
-
-
-
 InsetList::~InsetList()
 {
// If we begin storing a shared_ptr in the List
@@ -50,46 +32,39 @@
List::iterator it = list_.begin();
List::iterator end = list_.end();
for (; it != end; ++it) {
-   delete it->inset;
+   delete it->second;
}
 }
 
 
 InsetList::iterator InsetList::insetIterator(pos_type pos)
 {
-   InsetTable search_elem(pos, 0);
-   return lower_bound(list_.begin(), list_.end(), search_elem,
-  InsetTablePosLess());
+   return list_.find(pos);
 }
 
 
 InsetList::const_iterator InsetList::insetIterator(pos_type pos) const
 {
-   InsetTable search_elem(pos, 0);
-   return lower_bound(list_.begin(), list_.end(), search_elem,
-  InsetTablePosLess());
+   return list_.find(pos);
 }
 
 
 void InsetList::insert(Inset * inset, pos_type pos)
 {
-   List::iterator end = list_.end();
-   List::iterator it = insetIterator(pos);
-   if (it != end && it->pos == pos) {
+   List::iterator it = list_.find(pos);
+   if (it != list_.end())
lyxerr << "ERROR (InsetList::insert): "
   << "There is an inset in position: " << pos << endl;
-   } else {
-   list_.insert(it, InsetTable(pos, inset));
-   }
+   else
+   list_[pos] = inset;;
 }
 
 
 void InsetList::erase(pos_type pos)
 {
-   List::iterator end = list_.end();
-   List::iterator it = insetIterator(pos);
-   if (it != end && it->pos == pos) {
-   delete it->inset;
+   List::iterator it = list_.find(pos);
+   if (it != list_.end()) {
+   delete it->second;
list_.erase(it);
}
 }
@@ -97,11 +72,10 @@
 
 Inset * InsetList::release(pos_type pos)
 {
-   List::iterator end = list_.end();
-   List::iterator it = insetIterator(pos);
-   if (it != end && it->pos == pos) {
-   Inset * tmp = it->inset;
-   it->inset = 0;
+   List::iterator it = list_.find(pos);
+   if (it != list_.end()) {
+   Inset * tmp = it->second;
+   it->second = 0;
return tmp;
}
return 0;
@@ -110,31 +84,32 @@
 
 Inset * InsetList::get(pos_type pos) const
 {
-   List::const_iterator end = list_.end();
-   List::const_iterator it = insetIterator(pos);
-   if (it != end && it->pos == pos)
-   return it->inset;
+   List::const_iterator it = list_.find(pos);
+   if (it != list_.end())
+   return it->second;
return 0;
 }
 
 
 void InsetList::increasePosAfterPos(pos_type pos)
 {
-   List::iterator end = list_.end();
-   List::iterator it = insetIterator(pos);
-   for (; it != end; ++it) {
-   ++it->pos;
-   }
+   List oldlist = list_;
+   list_.clear();
+   List::iterator end = oldlist.end();
+   List::iterator it = oldlist.find(pos);
+   for (; it != end; ++it)
+   list_[it->first + 1] = it->second;
 }
 
 
 void InsetList::decreasePosAfterPos(pos_type pos)
 {
-   List::iterator end = list_.end();
-   List::iterator it = insetIterator(pos);
-   for (; it != end; ++it) {
-   --it->pos;
-   }
+   List oldlist = list_;
+   list_.clear();
+   List::iterator end = oldlist.end();
+   List::iterator it = oldlist.find(pos);
+   for (; it != end; ++it)
+   list_[it->first - 1] = it->second;
 }
 
 
Index: InsetList.h
===
--- InsetList.h (revision 18766)
+++ InsetList.h (working copy)
@@ -14,7 +14,7 @@
 
 #include "support/types.h"
 
-#include 
+#include 
 
 
 namespace lyx {
@@ -27,18 +27,8 @@
 class InsetList {
 public:
///
-   class InsetTable {
-   public:
-   ///
-   InsetTable(pos_type p, Inset * i) : pos(p), inset(i) {}
-   ///
-   pos_type pos;
-   ///
-   Inset * inset;
-   

Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Stefan Schimanski
Seems to be false alarm. getInset does not show up very much anymore  
without stdlib-debug. But there are still some interesting facts:


38% QPainter::drawText.
16% drawing of empty inline math insets (around every 20th character  
in the text)

16% for metrics calculation

I think the only way to really reduce the amount to draw is to switch  
to line based redrawing or even finer and relative coordinates for  
scrolling.


Stefan


Alfredo Braunstein wrote:

Abdelrazak Younes wrote:
I am OK with it but maybe the real problem is why getInset is so  
slow?

Looking at InsetList::insetIterator(pos_type pos), this is no wonder
really:

InsetList::iterator InsetList::insetIterator(pos_type pos)
{
InsetTable search_elem(pos, 0);
return lower_bound(list_.begin(), list_.end(), search_elem,
InsetTablePosLess());
}

InsetTable is basically 'pair', so this InsetList is
basically reimplementing std::map in a less efficient way. Just

Are you sure it's less efficient?


No, that was just a guess.


AFAICS this is O(ln n) just like std::map,
constants may vary (in one side or the other).
replacing the 'vector' with a 'map' will  
clean
halves the code. And then you could just use the standard map  
iterator
anywhere it makes sense; and I bet there is a lot of case were it  
make

sense:

The code will be a bit cleaner maybe...


For sure ;-)


but it is self-contained and clean
enough, and has been working flawlessly for ages... so be sure  
there is

really a gain if you are going to switch.


I am not proposing to switch before 1.5.0 but I might implement it  
just for fun and ask Stefan to try it out with Shark ;-)


Abdel.





PGP.sig
Description: Signierter Teil der Nachricht


Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Abdelrazak Younes

Abdelrazak Younes wrote:

Abdelrazak Younes wrote:

Alfredo Braunstein wrote:



but it is self-contained and clean
enough, and has been working flawlessly for ages... so be sure there is
really a gain if you are going to switch.


I am not proposing to switch before 1.5.0 but I might implement it 
just for fun and ask Stefan to try it out with Shark ;-)


Just for fun Stefan, could you try this out?


Forget about it, it won't compile because of the multitude of ->pos and 
->inset access.


Abdel.



Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Stefan Schimanski

Abdelrazak Younes wrote:

Alfredo Braunstein wrote:



but it is self-contained and clean
enough, and has been working flawlessly for ages... so be sure  
there is

really a gain if you are going to switch.
I am not proposing to switch before 1.5.0 but I might implement it  
just for fun and ask Stefan to try it out with Shark ;-)


Just for fun Stefan, could you try this out?



You saw my patch to your first reply? I includes nearly the same  
patch. But without stdlib-debug there is no problem at all with all  
that.


Stefan


PGP.sig
Description: Signierter Teil der Nachricht


Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Jean-Marc Lasgouttes
> "Abdelrazak" == Abdelrazak Younes <[EMAIL PROTECTED]> writes:

Abdelrazak> Maybe not faster but a lot cleaner. Am I am pretty sure
Abdelrazak> that it will make the cases similar to the one found by
Abdelrazak> Stefan easier to optimize.

Agreed.

Second thought: what is the first term of the map? If it is the
position, does this means that the map shall be recreated at each insertion?

JMarc


Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Jean-Marc Lasgouttes
> "Stefan" == Stefan Schimanski <[EMAIL PROTECTED]> writes:

Stefan> Seems to be false alarm. getInset does not show up very much
Stefan> anymore without stdlib-debug. But there are still some
Stefan> interesting facts:

Stefan> 38% QPainter::drawText. 

Looks more like what I would expect.

Stefan> 16% drawing of empty inline math insets (around every 20th
Stefan> character in the text) 

What do you mean?

Stefan> 16% for metrics calculation

JMarc


Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Abdelrazak Younes

Stefan Schimanski wrote:

Abdelrazak Younes wrote:

Alfredo Braunstein wrote:



but it is self-contained and clean
enough, and has been working flawlessly for ages... so be sure there is
really a gain if you are going to switch.
I am not proposing to switch before 1.5.0 but I might implement it 
just for fun and ask Stefan to try it out with Shark ;-)


Just for fun Stefan, could you try this out?



You saw my patch to your first reply? I includes nearly the same patch. 
But without stdlib-debug there is no problem at all with all that.


OK.

Abdel.



Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Abdelrazak Younes

Stefan Schimanski wrote:
Seems to be false alarm. getInset does not show up very much anymore 
without stdlib-debug. But there are still some interesting facts:


38% QPainter::drawText.


This was expected on Mac. Still, IIRC the number is lower than what 
Bennett used to report a while ago. It shows that Qt4.3 is much better 
at drawing on Mac than previous version. Hopefully this number will keep 
decreasing with further release.



16% drawing of empty inline math insets (around every 20th character in 
the text)


What is that?


16% for metrics calculation


Calculation or hash table lookup?



I think the only way to really reduce the amount to draw is to switch to 
line based redrawing or even finer and relative coordinates for scrolling.


Once we re-organize the background painting in rowpainter (thus getting 
rid of wide() etc) I believe we will see a nice speedup because only the 
current line will have to be redrawn in all cases (within Inset or not).


Abdel.



Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Abdelrazak Younes

Jean-Marc Lasgouttes wrote:

"Abdelrazak" == Abdelrazak Younes <[EMAIL PROTECTED]> writes:


Abdelrazak> Maybe not faster but a lot cleaner. Am I am pretty sure
Abdelrazak> that it will make the cases similar to the one found by
Abdelrazak> Stefan easier to optimize.

Agreed.

Second thought: what is the first term of the map?


In my first implementation the position. The atavantage is that then the 
Inset are ordered by position in memory and the code relies on that I 
think (but I am not sure). But the disavantage is:



If it is the
position, does this means that the map shall be recreated at each insertion?


Right but I reckon this is not very costly, because we do something 
similar in the Paragraph list when inserting or deleting a paragraph.


Abdel.



Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Stefan Schimanski


Am 14.06.2007 um 18:44 schrieb Abdelrazak Younes:


Stefan Schimanski wrote:
Seems to be false alarm. getInset does not show up very much  
anymore without stdlib-debug. But there are still some interesting  
facts:

38% QPainter::drawText.


This was expected on Mac. Still, IIRC the number is lower than what  
Bennett used to report a while ago. It shows that Qt4.3 is much  
better at drawing on Mac than previous version. Hopefully this  
number will keep decreasing with further release.



16% drawing of empty inline math insets (around every 20th  
character in the text)



What is that?


Basically the InsetMathHull::draw call with everything which follows.  
So at the end some QLPainter::line calls which turn out to be quite  
expensive IMO.



16% for metrics calculation


Calculation or hash table lookup?


The whole updateMetrics call, everything there summed up.

I think the only way to really reduce the amount to draw is to  
switch to line based redrawing or even finer and relative  
coordinates for scrolling.


Once we re-organize the background painting in rowpainter (thus  
getting rid of wide() etc) I believe we will see a nice speedup  
because only the current line will have to be redrawn in all cases  
(within Inset or not).


That sounds good.

Stefan


PGP.sig
Description: Signierter Teil der Nachricht


Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Andre Poenitz
On Thu, Jun 14, 2007 at 05:05:32PM +0200, Stefan Schimanski wrote:
> I did some profiling of paragraph drawing. 20% of the whole time  
> while inserting characters and redrawing the screen was taken by  
> Paragraph::getInset calls, each for every character. This is stupid.  
> See the patch below for a loop iterating over the insets of a  
> paragraph instead. O(insetnumber) instead of O(charnumber * ln  
> insetnumber).
> 
> Stefan
> 
> Index: src/rowpainter.cpp
> ===
> --- src/rowpainter.cpp(Revision 18765)
> +++ src/rowpainter.cpp(Arbeitskopie)
> @@ -958,10 +958,11 @@
>   // done here.
>   // JSpitzm: We should aim at removing wide() altogether 
>   while  retaining
>   // typing speed within insets.
> - for (pos_type i = rit->pos() ; i != rit->endpos(); ++i) {
> - Inset const * const in = par.getInset(i);
> - if (in) {
> - InsetText * t = const_cast *>(in->asTextInset());
> + InsetList::const_iterator iit = 
> par.insetlist.insetIterator(rit->pos());
> + InsetList::const_iterator iend = par.insetlist.end();
> + for (; iit != iend && iit->pos < rit->endpos(); ++iit) {
> + if (iit->inset) {
> + InsetText * t = const_cast *>(iit->inset->asTextInset());
>   if (t)
>   t->setWide(in_inset_alone_on_row
>  && leftEdgeFixed


Good catch.  Patch is fine with me.

[And I continue hating that wide() business ;-}]

Andre'



Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Dov Feldstern

Jean-Marc Lasgouttes wrote:

"Abdelrazak" == Abdelrazak Younes <[EMAIL PROTECTED]> writes:


Abdelrazak> Maybe not faster but a lot cleaner. Am I am pretty sure
Abdelrazak> that it will make the cases similar to the one found by
Abdelrazak> Stefan easier to optimize.

Agreed.

Second thought: what is the first term of the map? If it is the
position, does this means that the map shall be recreated at each insertion?

JMarc



Hmm, I just came across this yesterday when trying to figure out what 
was going on with bug 3011, and wondered about it. I'm not sure if this 
is what you mean or not, but it might be relevant...


http://www.lyx.org/trac/browser/lyx-devel/trunk/src/Paragraph.cpp?rev=18599#L446



Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Andre Poenitz
On Thu, Jun 14, 2007 at 05:40:12PM +0200, Alfredo Braunstein wrote:
> Abdelrazak Younes wrote:
> 
> > I am OK with it but maybe the real problem is why getInset is so slow?
> > Looking at InsetList::insetIterator(pos_type pos), this is no wonder
> > really:
> > 
> > InsetList::iterator InsetList::insetIterator(pos_type pos)
> > {
> > InsetTable search_elem(pos, 0);
> > return lower_bound(list_.begin(), list_.end(), search_elem,
> > InsetTablePosLess());
> > }
> > 
> > InsetTable is basically 'pair', so this InsetList is
> > basically reimplementing std::map in a less efficient way.

How do you [Abdel] arrive at the conclusion 'less efficient'?

> Are you sure it's less efficient? AFAICS this is O(ln n) just like std::map,
> constants may vary (in one side or the other). 

A sorted vector filled should be cheaper than a map in any case.

> > replacing the 'vector' with a 'map' will clean
> > halves the code. And then you could just use the standard map iterator
> > anywhere it makes sense; and I bet there is a lot of case were it make
> > sense:
> 
> The code will be a bit cleaner maybe... but it is self-contained and clean
> enough, and has been working flawlessly for ages... so be sure there is
> really a gain if you are going to switch.

Right.

Andre'


Re: 20% speedup of paragraph redraw with simple patch

2007-06-14 Thread Andre Poenitz
On Thu, Jun 14, 2007 at 05:49:53PM +0200, Abdelrazak Younes wrote:
> >Moreover, it remains to be seen whether the map is faster in the cases
> >where the container typically has at most 10 elements. It might be
> >that a stupid plain loop is faster...
> 
> Maybe not faster but a lot cleaner.

You may have noticed that users are complaining about speed, not on code
cleanliness.

Andre'