unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#24012: 25.0.95; forward-comment backwards takes O(n^2)
@ 2016-07-17 11:04 Leo Liu
  2016-07-17 12:12 ` Eli Zaretskii
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: Leo Liu @ 2016-07-17 11:04 UTC (permalink / raw)
  To: 24012

[-- Attachment #1: Type: text/plain, Size: 341 bytes --]


1. Use the attached file as an example, open it in emacs in ruby-mode
2. Move point to end of buffer and eval (forward-comment (- (point)))

The last step takes about 0.25 seconds on my MacBook 3 GHz Intel Core
i7. If you double the lines of comments, the time increase by 4 folds.

Any idea why forward-comment backwards is so slow?

Leo


[-- Attachment #2: tt.rb --]
[-- Type: text/plain, Size: 24526 bytes --]

### PropEr is free software: you can redistribute it and/or modify
### it under the terms of the GNU General Public License as published by
### the Free Software Foundation, either version 3 of the License, or
### (at your option) any later version.
###
### PropEr is distributed in the hope that it will be useful,
### but WITHOUT ANY WARRANTY; without even the implied warranty of
### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
### GNU General Public License for more details.
###
### You should have received a copy of the GNU General Public License
### along with PropEr.  If not, see <http://www.gnu.org/licenses/>.

### @copyright 2010-2016 Manolis Papadakis, Eirini Arvaniti and Kostis Sagonas
### @version {@version}
### @author Eirini Arvaniti

### @doc This module defines the `proper_fsm' behaviour, useful for testing
### systems that can be modeled as finite state machines. That is, a finite
### collection of named states and transitions between them. `{@module}' is
### closely related to {@link proper_statem} and is, in fact, implemented in
### terms of that. Testcases generated using `{@module}' will be on precisely
### the same form as testcases generated using {@link proper_statem}. The
### difference lies in the way the callback modules are specified.
### The relation between {@link proper_statem} and `{@module}' is similar
### to the one between `gen_server' and `gen_fsm' in OTP libraries.
###
### Due to name conflicts with functions automatically imported from
### {@link proper_statem}, a fully qualified call is needed in order to
### use the  <a href="#index">API functions </a> of `{@module}'.
###
### === The states of the finite state machine ===
### Following the convention used in `gen_fsm behaviour', the state is
### separated into a `StateName::'{@type state_name()} and some
### `StateData::'{@type state_data()}. `StateName' is used to denote a state
### of the finite state machine and `StateData' is any relevant information
### that has to be stored in the model state. States are fully
### represented as tuples `{StateName, StateData}'.
###
### `StateName' is usually an atom (i.e. the name of the state), but can also
### be a tuple. In the latter case, the first element of the tuple must be an
### atom specifying the name of the state, whereas the rest of the elements can
### be arbitrary terms specifying state attributes. For example, when
### implementing the fsm of an elevator which can reach N different floors, the
### `StateName' for each floor could be `{floor,K}, 1 <= K <= N'.<br/>
### `StateData' can be an arbitrary term, but is usually a record.
###
### === Transitions between states ===
### A transition ({@type transition()}) is represented as a tuple
### `{TargetState, {call,M,F,A}}'. This means that performing the specified
### symbolic call at the current state of the fsm will lead to `TargetState'.
### The atom `history' can be used as `TargetState' to denote that a transition
### does not change the current state of the fsm.
###
### === The callback functions ===
### The following functions must be exported from the callback module
### implementing the finite state machine:
### <ul>
### <li> `initial_state() ->' {@type state_name()}
###   <p>Specifies the initial state of the finite state machine. As with
###   `proper_statem:initial_state/0', its result should be deterministic.
###   </p></li>
### <li> `initial_state_data() ::' {@type state_data()}
###   <p>Specifies what the state data should initially contain. Its result
###   should be deterministic</p></li>
### <li> `StateName(S::'{@type state_data()}`) ::'
###        `['{@type transition()}`]'
###   <p>There should be one instance of this function for each reachable
###   state `StateName' of the finite state machine. In case `StateName' is a
###   tuple the function takes a different form, described just below. The
###   function returns a list of possible transitions ({@type transition()})
###   from the current state.
###   At command generation time, the instance of this function with the same
###   name as the current state's name is called to return the list of possible
###   transitions. Then, PropEr will randomly choose a transition and,
###   according to that, generate the next symbolic call to be included in the
###   command sequence. However, before the call is actually included, a
###   precondition that might impose constraints on `StateData' is checked.<br/>
###   Note also that PropEr detects transitions that would raise an exception
###   of class `<error>' at generation time (not earlier) and does not choose
###   them. This feature can be used to include conditional transitions that
###   depend on the `StateData'.</p></li>
### <li> `StateName(Attr1::term(), ..., AttrN::term(),
###                 S::'{@type state_data()}`) ::'
###        `['{@type transition()}`]'
###   <p>There should be one instance of this function for each reachable state
###   `{StateName,Attr1,...,AttrN}' of the finite state machine. The function
###   has similar beaviour to `StateName/1', described above.</p></li>
### <li> `weight(From::'{@type state_name()}`,
###              Target::'{@type state_name()}`,
###              Call::'{@type symbolic_call()}`) -> integer()'
###   <p>This is an optional callback. When it is not defined (or not exported),
###   transitions are chosen with equal probability. When it is defined, it
###   assigns an integer weight to transitions from `From' to `Target'
###   triggered by symbolic call `Call'. In this case, each transition is chosen
###   with probability proportional to the weight assigned.</p></li>
### <li> `precondition(From::'{@type state_name()}`,
###                    Target::'{@type state_name()}`,
###                    StateData::'{@type state_data()}`,
###                    Call::'{@type symbolic_call()}`) -> boolean()'
###   <p>Similar to `proper_statem:precondition/2'. Specifies the
###   precondition that should hold about `StateData' so that `Call' can be
###   included in the command sequence. In case precondition doesn't hold, a
###   new transition is chosen using the appropriate `StateName/1' generator.
###   It is possible for more than one transitions to be triggered by the same
###   symbolic call and lead to different target states. In this case, at most
###   one of the target states may have a true precondition. Otherwise, PropEr
###   will not be able to detect which transition was chosen and an exception
###   will be raised.</p></li>
### <li> `postcondition(From::'{@type state_name()}`,
###                     Target::'{@type state_name()}`,
###                     StateData::'{@type state_data()}`,
###                     Call::'{@type symbolic_call()}`,
###                     Res::'{@type cmd_result()}`) -> boolean()'
###   <p>Similar to `proper_statem:postcondition/3'. Specifies the
###   postcondition that should hold about the result `Res' of the evaluation
###   of `Call'.</p></li>
### <li> `next_state_data(From::'{@type state_name()}`,
###                       Target::'{@type state_name()}`,
###                       StateData::'{@type state_data()}`,
###                       Res::'{@type cmd_result()}`,
###                       Call::'{@type symbolic_call()}`) ->'
###        {@type state_data()}
###   <p>Similar to `proper_statem:next_state/3'. Specifies how the
###   transition from `FromState' to `Target' triggered by `Call' affects the
###   `StateData'. `Res' refers to the result of `Call' and can be either
###   symbolic or dynamic.</p></li>
### </ul>
###
### === The property used ===
### This is an example of a property that can be used to test a
### finite state machine specification:
###
### ```prop_fsm() ->
###        ?FORALL(Cmds, proper_fsm:commands(?MODULE),
###                begin
###                    {_History, _State, Result} = proper_fsm:run_commands(?MODULE, Cmds),
###                    cleanup(),
###                    Result =:= ok
###                end).'''
### @end
### Copyright 2010-2016 Manolis Papadakis <manopapad@gmail.com>,
###                     Eirini Arvaniti <eirinibob@gmail.com>
###                 and Kostis Sagonas <kostis@cs.ntua.gr>
###
### This file is part of PropEr.
###
### PropEr is free software: you can redistribute it and/or modify
### it under the terms of the GNU General Public License as published by
### the Free Software Foundation, either version 3 of the License, or
### (at your option) any later version.
###
### PropEr is distributed in the hope that it will be useful,
### but WITHOUT ANY WARRANTY; without even the implied warranty of
### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
### GNU General Public License for more details.
###
### You should have received a copy of the GNU General Public License
### along with PropEr.  If not, see <http://www.gnu.org/licenses/>.

### @copyright 2010-2016 Manolis Papadakis, Eirini Arvaniti and Kostis Sagonas
### @version {@version}
### @author Eirini Arvaniti

### @doc This module defines the `proper_fsm' behaviour, useful for testing
### systems that can be modeled as finite state machines. That is, a finite
### collection of named states and transitions between them. `{@module}' is
### closely related to {@link proper_statem} and is, in fact, implemented in
### terms of that. Testcases generated using `{@module}' will be on precisely
### the same form as testcases generated using {@link proper_statem}. The
### difference lies in the way the callback modules are specified.
### The relation between {@link proper_statem} and `{@module}' is similar
### to the one between `gen_server' and `gen_fsm' in OTP libraries.
###
### Due to name conflicts with functions automatically imported from
### {@link proper_statem}, a fully qualified call is needed in order to
### use the  <a href="#index">API functions </a> of `{@module}'.
###
### === The states of the finite state machine ===
### Following the convention used in `gen_fsm behaviour', the state is
### separated into a `StateName::'{@type state_name()} and some
### `StateData::'{@type state_data()}. `StateName' is used to denote a state
### of the finite state machine and `StateData' is any relevant information
### that has to be stored in the model state. States are fully
### represented as tuples `{StateName, StateData}'.
###
### `StateName' is usually an atom (i.e. the name of the state), but can also
### be a tuple. In the latter case, the first element of the tuple must be an
### atom specifying the name of the state, whereas the rest of the elements can
### be arbitrary terms specifying state attributes. For example, when
### implementing the fsm of an elevator which can reach N different floors, the
### `StateName' for each floor could be `{floor,K}, 1 <= K <= N'.<br/>
### `StateData' can be an arbitrary term, but is usually a record.
###
### === Transitions between states ===
### A transition ({@type transition()}) is represented as a tuple
### `{TargetState, {call,M,F,A}}'. This means that performing the specified
### symbolic call at the current state of the fsm will lead to `TargetState'.
### The atom `history' can be used as `TargetState' to denote that a transition
### does not change the current state of the fsm.
###
### === The callback functions ===
### The following functions must be exported from the callback module
### implementing the finite state machine:
### <ul>
### <li> `initial_state() ->' {@type state_name()}
###   <p>Specifies the initial state of the finite state machine. As with
###   `proper_statem:initial_state/0', its result should be deterministic.
###   </p></li>
### <li> `initial_state_data() ::' {@type state_data()}
###   <p>Specifies what the state data should initially contain. Its result
###   should be deterministic</p></li>
### <li> `StateName(S::'{@type state_data()}`) ::'
###        `['{@type transition()}`]'
###   <p>There should be one instance of this function for each reachable
###   state `StateName' of the finite state machine. In case `StateName' is a
###   tuple the function takes a different form, described just below. The
###   function returns a list of possible transitions ({@type transition()})
###   from the current state.
###   At command generation time, the instance of this function with the same
###   name as the current state's name is called to return the list of possible
###   transitions. Then, PropEr will randomly choose a transition and,
###   according to that, generate the next symbolic call to be included in the
###   command sequence. However, before the call is actually included, a
###   precondition that might impose constraints on `StateData' is checked.<br/>
###   Note also that PropEr detects transitions that would raise an exception
###   of class `<error>' at generation time (not earlier) and does not choose
###   them. This feature can be used to include conditional transitions that
###   depend on the `StateData'.</p></li>
### <li> `StateName(Attr1::term(), ..., AttrN::term(),
###                 S::'{@type state_data()}`) ::'
###        `['{@type transition()}`]'
###   <p>There should be one instance of this function for each reachable state
###   `{StateName,Attr1,...,AttrN}' of the finite state machine. The function
###   has similar beaviour to `StateName/1', described above.</p></li>
### <li> `weight(From::'{@type state_name()}`,
###              Target::'{@type state_name()}`,
###              Call::'{@type symbolic_call()}`) -> integer()'
###   <p>This is an optional callback. When it is not defined (or not exported),
###   transitions are chosen with equal probability. When it is defined, it
###   assigns an integer weight to transitions from `From' to `Target'
###   triggered by symbolic call `Call'. In this case, each transition is chosen
###   with probability proportional to the weight assigned.</p></li>
### <li> `precondition(From::'{@type state_name()}`,
###                    Target::'{@type state_name()}`,
###                    StateData::'{@type state_data()}`,
###                    Call::'{@type symbolic_call()}`) -> boolean()'
###   <p>Similar to `proper_statem:precondition/2'. Specifies the
###   precondition that should hold about `StateData' so that `Call' can be
###   included in the command sequence. In case precondition doesn't hold, a
###   new transition is chosen using the appropriate `StateName/1' generator.
###   It is possible for more than one transitions to be triggered by the same
###   symbolic call and lead to different target states. In this case, at most
###   one of the target states may have a true precondition. Otherwise, PropEr
###   will not be able to detect which transition was chosen and an exception
###   will be raised.</p></li>
### <li> `postcondition(From::'{@type state_name()}`,
###                     Target::'{@type state_name()}`,
###                     StateData::'{@type state_data()}`,
###                     Call::'{@type symbolic_call()}`,
###                     Res::'{@type cmd_result()}`) -> boolean()'
###   <p>Similar to `proper_statem:postcondition/3'. Specifies the
###   postcondition that should hold about the result `Res' of the evaluation
###   of `Call'.</p></li>
### <li> `next_state_data(From::'{@type state_name()}`,
###                       Target::'{@type state_name()}`,
###                       StateData::'{@type state_data()}`,
###                       Res::'{@type cmd_result()}`,
###                       Call::'{@type symbolic_call()}`) ->'
###        {@type state_data()}
###   <p>Similar to `proper_statem:next_state/3'. Specifies how the
###   transition from `FromState' to `Target' triggered by `Call' affects the
###   `StateData'. `Res' refers to the result of `Call' and can be either
###   symbolic or dynamic.</p></li>
### </ul>
###
### === The property used ===
### This is an example of a property that can be used to test a
### finite state machine specification:
###
### ```prop_fsm() ->
###        ?FORALL(Cmds, proper_fsm:commands(?MODULE),
###                begin
###                    {_History, _State, Result} = proper_fsm:run_commands(?MODULE, Cmds),
###                    cleanup(),
###                    Result =:= ok
###                end).'''
### @end
### Copyright 2010-2016 Manolis Papadakis <manopapad@gmail.com>,
###                     Eirini Arvaniti <eirinibob@gmail.com>
###                 and Kostis Sagonas <kostis@cs.ntua.gr>
###
### This file is part of PropEr.
###
### PropEr is free software: you can redistribute it and/or modify
### it under the terms of the GNU General Public License as published by
### the Free Software Foundation, either version 3 of the License, or
### (at your option) any later version.
###
### PropEr is distributed in the hope that it will be useful,
### but WITHOUT ANY WARRANTY; without even the implied warranty of
### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
### GNU General Public License for more details.
###
### You should have received a copy of the GNU General Public License
### along with PropEr.  If not, see <http://www.gnu.org/licenses/>.

### @copyright 2010-2016 Manolis Papadakis, Eirini Arvaniti and Kostis Sagonas
### @version {@version}
### @author Eirini Arvaniti

### @doc This module defines the `proper_fsm' behaviour, useful for testing
### systems that can be modeled as finite state machines. That is, a finite
### collection of named states and transitions between them. `{@module}' is
### closely related to {@link proper_statem} and is, in fact, implemented in
### terms of that. Testcases generated using `{@module}' will be on precisely
### the same form as testcases generated using {@link proper_statem}. The
### difference lies in the way the callback modules are specified.
### The relation between {@link proper_statem} and `{@module}' is similar
### to the one between `gen_server' and `gen_fsm' in OTP libraries.
###
### Due to name conflicts with functions automatically imported from
### {@link proper_statem}, a fully qualified call is needed in order to
### use the  <a href="#index">API functions </a> of `{@module}'.
###
### === The states of the finite state machine ===
### Following the convention used in `gen_fsm behaviour', the state is
### separated into a `StateName::'{@type state_name()} and some
### `StateData::'{@type state_data()}. `StateName' is used to denote a state
### of the finite state machine and `StateData' is any relevant information
### that has to be stored in the model state. States are fully
### represented as tuples `{StateName, StateData}'.
###
### `StateName' is usually an atom (i.e. the name of the state), but can also
### be a tuple. In the latter case, the first element of the tuple must be an
### atom specifying the name of the state, whereas the rest of the elements can
### be arbitrary terms specifying state attributes. For example, when
### implementing the fsm of an elevator which can reach N different floors, the
### `StateName' for each floor could be `{floor,K}, 1 <= K <= N'.<br/>
### `StateData' can be an arbitrary term, but is usually a record.
###
### === Transitions between states ===
### A transition ({@type transition()}) is represented as a tuple
### `{TargetState, {call,M,F,A}}'. This means that performing the specified
### symbolic call at the current state of the fsm will lead to `TargetState'.
### The atom `history' can be used as `TargetState' to denote that a transition
### does not change the current state of the fsm.
###
### === The callback functions ===
### The following functions must be exported from the callback module
### implementing the finite state machine:
### <ul>
### <li> `initial_state() ->' {@type state_name()}
###   <p>Specifies the initial state of the finite state machine. As with
###   `proper_statem:initial_state/0', its result should be deterministic.
###   </p></li>
### <li> `initial_state_data() ::' {@type state_data()}
###   <p>Specifies what the state data should initially contain. Its result
###   should be deterministic</p></li>
### <li> `StateName(S::'{@type state_data()}`) ::'
###        `['{@type transition()}`]'
###   <p>There should be one instance of this function for each reachable
###   state `StateName' of the finite state machine. In case `StateName' is a
###   tuple the function takes a different form, described just below. The
###   function returns a list of possible transitions ({@type transition()})
###   from the current state.
###   At command generation time, the instance of this function with the same
###   name as the current state's name is called to return the list of possible
###   transitions. Then, PropEr will randomly choose a transition and,
###   according to that, generate the next symbolic call to be included in the
###   command sequence. However, before the call is actually included, a
###   precondition that might impose constraints on `StateData' is checked.<br/>
###   Note also that PropEr detects transitions that would raise an exception
###   of class `<error>' at generation time (not earlier) and does not choose
###   them. This feature can be used to include conditional transitions that
###   depend on the `StateData'.</p></li>
### <li> `StateName(Attr1::term(), ..., AttrN::term(),
###                 S::'{@type state_data()}`) ::'
###        `['{@type transition()}`]'
###   <p>There should be one instance of this function for each reachable state
###   `{StateName,Attr1,...,AttrN}' of the finite state machine. The function
###   has similar beaviour to `StateName/1', described above.</p></li>
### <li> `weight(From::'{@type state_name()}`,
###              Target::'{@type state_name()}`,
###              Call::'{@type symbolic_call()}`) -> integer()'
###   <p>This is an optional callback. When it is not defined (or not exported),
###   transitions are chosen with equal probability. When it is defined, it
###   assigns an integer weight to transitions from `From' to `Target'
###   triggered by symbolic call `Call'. In this case, each transition is chosen
###   with probability proportional to the weight assigned.</p></li>
### <li> `precondition(From::'{@type state_name()}`,
###                    Target::'{@type state_name()}`,
###                    StateData::'{@type state_data()}`,
###                    Call::'{@type symbolic_call()}`) -> boolean()'
###   <p>Similar to `proper_statem:precondition/2'. Specifies the
###   precondition that should hold about `StateData' so that `Call' can be
###   included in the command sequence. In case precondition doesn't hold, a
###   new transition is chosen using the appropriate `StateName/1' generator.
###   It is possible for more than one transitions to be triggered by the same
###   symbolic call and lead to different target states. In this case, at most
###   one of the target states may have a true precondition. Otherwise, PropEr
###   will not be able to detect which transition was chosen and an exception
###   will be raised.</p></li>
### <li> `postcondition(From::'{@type state_name()}`,
###                     Target::'{@type state_name()}`,
###                     StateData::'{@type state_data()}`,
###                     Call::'{@type symbolic_call()}`,
###                     Res::'{@type cmd_result()}`) -> boolean()'
###   <p>Similar to `proper_statem:postcondition/3'. Specifies the
###   postcondition that should hold about the result `Res' of the evaluation
###   of `Call'.</p></li>
### <li> `next_state_data(From::'{@type state_name()}`,
###                       Target::'{@type state_name()}`,
###                       StateData::'{@type state_data()}`,
###                       Res::'{@type cmd_result()}`,
###                       Call::'{@type symbolic_call()}`) ->'
###        {@type state_data()}
###   <p>Similar to `proper_statem:next_state/3'. Specifies how the
###   transition from `FromState' to `Target' triggered by `Call' affects the
###   `StateData'. `Res' refers to the result of `Call' and can be either
###   symbolic or dynamic.</p></li>
### </ul>
###
### === The property used ===
### This is an example of a property that can be used to test a
### finite state machine specification:
###
### ```prop_fsm() ->
###        ?FORALL(Cmds, proper_fsm:commands(?MODULE),
###                begin
###                    {_History, _State, Result} = proper_fsm:run_commands(?MODULE, Cmds),
###                    cleanup(),
###                    Result =:= ok
###                end).'''
### @end

^ permalink raw reply	[flat|nested] 10+ messages in thread

* bug#24012: 25.0.95; forward-comment backwards takes O(n^2)
  2016-07-17 11:04 bug#24012: 25.0.95; forward-comment backwards takes O(n^2) Leo Liu
@ 2016-07-17 12:12 ` Eli Zaretskii
  2016-07-18  0:15   ` Leo Liu
  2016-07-17 13:39 ` Andreas Röhler
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 10+ messages in thread
From: Eli Zaretskii @ 2016-07-17 12:12 UTC (permalink / raw)
  To: Leo Liu; +Cc: 24012

> From: Leo Liu <sdl.web@gmail.com>
> Date: Sun, 17 Jul 2016 19:04:18 +0800
> 
> 1. Use the attached file as an example, open it in emacs in ruby-mode
> 2. Move point to end of buffer and eval (forward-comment (- (point)))
> 
> The last step takes about 0.25 seconds on my MacBook 3 GHz Intel Core
> i7. If you double the lines of comments, the time increase by 4 folds.
> 
> Any idea why forward-comment backwards is so slow?

Because search functions cannot really search backwards?





^ permalink raw reply	[flat|nested] 10+ messages in thread

* bug#24012: 25.0.95; forward-comment backwards takes O(n^2)
  2016-07-17 11:04 bug#24012: 25.0.95; forward-comment backwards takes O(n^2) Leo Liu
  2016-07-17 12:12 ` Eli Zaretskii
@ 2016-07-17 13:39 ` Andreas Röhler
  2017-12-25 15:24 ` Dmitry Gutov
  2019-09-29  5:15 ` Stefan Kangas
  3 siblings, 0 replies; 10+ messages in thread
From: Andreas Röhler @ 2016-07-17 13:39 UTC (permalink / raw)
  To: 24012



On 17.07.2016 13:04, Leo Liu wrote:
> 1. Use the attached file as an example, open it in emacs in ruby-mode
> 2. Move point to end of buffer and eval (forward-comment (- (point)))
>
> The last step takes about 0.25 seconds on my MacBook 3 GHz Intel Core
> i7. If you double the lines of comments, the time increase by 4 folds.
>
> Any idea why forward-comment backwards is so slow?
>
> Leo
>

With last line

### @end (forward-comment (- (point)))

evaluation last expression doesn't move backward at all, returns nil

GNU Emacs 25.0.95.1 (i686-pc-linux-gnu, GTK+ Version 3.14.5) of 2016-06-12





^ permalink raw reply	[flat|nested] 10+ messages in thread

* bug#24012: 25.0.95; forward-comment backwards takes O(n^2)
  2016-07-17 12:12 ` Eli Zaretskii
@ 2016-07-18  0:15   ` Leo Liu
  2016-07-18  2:36     ` Eli Zaretskii
  0 siblings, 1 reply; 10+ messages in thread
From: Leo Liu @ 2016-07-18  0:15 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 24012

On 2016-07-17 15:12 +0300, Eli Zaretskii wrote:
> Because search functions cannot really search backwards?

But by changing the major mode to octave-mode you get a 12 times speedup
without doing anything.

Leo





^ permalink raw reply	[flat|nested] 10+ messages in thread

* bug#24012: 25.0.95; forward-comment backwards takes O(n^2)
  2016-07-18  0:15   ` Leo Liu
@ 2016-07-18  2:36     ` Eli Zaretskii
  2016-07-18  3:05       ` Leo Liu
  0 siblings, 1 reply; 10+ messages in thread
From: Eli Zaretskii @ 2016-07-18  2:36 UTC (permalink / raw)
  To: Leo Liu; +Cc: 24012

> From:  Leo Liu <sdl.web@gmail.com>
> Cc: 24012@debbugs.gnu.org
> Date: Mon, 18 Jul 2016 08:15:44 +0800
> 
> On 2016-07-17 15:12 +0300, Eli Zaretskii wrote:
> > Because search functions cannot really search backwards?
> 
> But by changing the major mode to octave-mode you get a 12 times speedup
> without doing anything.

Profile it.  One guess is that the different comment syntax somehow
causes this.  But that's a guess.





^ permalink raw reply	[flat|nested] 10+ messages in thread

* bug#24012: 25.0.95; forward-comment backwards takes O(n^2)
  2016-07-18  2:36     ` Eli Zaretskii
@ 2016-07-18  3:05       ` Leo Liu
  2016-07-18 14:34         ` Eli Zaretskii
  0 siblings, 1 reply; 10+ messages in thread
From: Leo Liu @ 2016-07-18  3:05 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 24012

On 2016-07-18 05:36 +0300, Eli Zaretskii wrote:
> Profile it.  One guess is that the different comment syntax somehow
> causes this.  But that's a guess.

How to profile it?

Before reporting this bug I have been trying profiler and elp and came
to the conclusion that forward-comment was the issue. How do you go
further than forward-comment which is in C which I only have limited
experience with?

Leo





^ permalink raw reply	[flat|nested] 10+ messages in thread

* bug#24012: 25.0.95; forward-comment backwards takes O(n^2)
  2016-07-18  3:05       ` Leo Liu
@ 2016-07-18 14:34         ` Eli Zaretskii
  0 siblings, 0 replies; 10+ messages in thread
From: Eli Zaretskii @ 2016-07-18 14:34 UTC (permalink / raw)
  To: Leo Liu; +Cc: 24012

> From:  Leo Liu <sdl.web@gmail.com>
> Cc: 24012@debbugs.gnu.org
> Date: Mon, 18 Jul 2016 11:05:01 +0800
> 
> On 2016-07-18 05:36 +0300, Eli Zaretskii wrote:
> > Profile it.  One guess is that the different comment syntax somehow
> > causes this.  But that's a guess.
> 
> How to profile it?
> 
> Before reporting this bug I have been trying profiler and elp and came
> to the conclusion that forward-comment was the issue. How do you go
> further than forward-comment which is in C which I only have limited
> experience with?

I meant a comparative profile between the two major modes.

As for profiling primitives, there's 'prof' that can make wonders, if
you are using a platform which it supports.

Thanks.





^ permalink raw reply	[flat|nested] 10+ messages in thread

* bug#24012: 25.0.95; forward-comment backwards takes O(n^2)
  2016-07-17 11:04 bug#24012: 25.0.95; forward-comment backwards takes O(n^2) Leo Liu
  2016-07-17 12:12 ` Eli Zaretskii
  2016-07-17 13:39 ` Andreas Röhler
@ 2017-12-25 15:24 ` Dmitry Gutov
  2019-09-29  5:15 ` Stefan Kangas
  3 siblings, 0 replies; 10+ messages in thread
From: Dmitry Gutov @ 2017-12-25 15:24 UTC (permalink / raw)
  To: Leo Liu, 24012

On 7/17/16 2:04 PM, Leo Liu wrote:
> 
> 1. Use the attached file as an example, open it in emacs in ruby-mode
> 2. Move point to end of buffer and eval (forward-comment (- (point)))
> 
> The last step takes about 0.25 seconds on my MacBook 3 GHz Intel Core
> i7. If you double the lines of comments, the time increase by 4 folds.

FWIW, it looks fixed in the master branch now.

Probably by 14b95587520959c5b54356547a0a69932a9bb480, so no idea what 
exactly was causing it.





^ permalink raw reply	[flat|nested] 10+ messages in thread

* bug#24012: 25.0.95; forward-comment backwards takes O(n^2)
  2016-07-17 11:04 bug#24012: 25.0.95; forward-comment backwards takes O(n^2) Leo Liu
                   ` (2 preceding siblings ...)
  2017-12-25 15:24 ` Dmitry Gutov
@ 2019-09-29  5:15 ` Stefan Kangas
  2019-11-08  3:59   ` Stefan Kangas
  3 siblings, 1 reply; 10+ messages in thread
From: Stefan Kangas @ 2019-09-29  5:15 UTC (permalink / raw)
  To: Dmitry Gutov; +Cc: 24012, Leo Liu

Dmitry Gutov <dgutov@yandex.ru> writes:

> On 7/17/16 2:04 PM, Leo Liu wrote:
>> 1. Use the attached file as an example, open it in emacs in ruby-mode
>> 2. Move point to end of buffer and eval (forward-comment (- (point)))
>> The last step takes about 0.25 seconds on my MacBook 3 GHz Intel Core
>> i7. If you double the lines of comments, the time increase by 4 folds.
>
> FWIW, it looks fixed in the master branch now.
>
> Probably by 14b95587520959c5b54356547a0a69932a9bb480, so no idea what exactly
> was causing it.

Indeed.  I only see O(n) on current master -- that is, if I use the
source code from the original report, and double the amount of lines
by C-x h M-w C-y, the time to evaluate this expression in a buffer
only doubles:

    (progn (end-of-buffer) (forward-comment (- (point))))

Leo, are you still seeing this issue?  If I don't hear back within a
couple of weeks, I'll just assume that this has been fixed and close
this bug.

Best regards,
Stefan Kangas





^ permalink raw reply	[flat|nested] 10+ messages in thread

* bug#24012: 25.0.95; forward-comment backwards takes O(n^2)
  2019-09-29  5:15 ` Stefan Kangas
@ 2019-11-08  3:59   ` Stefan Kangas
  0 siblings, 0 replies; 10+ messages in thread
From: Stefan Kangas @ 2019-11-08  3:59 UTC (permalink / raw)
  To: Dmitry Gutov; +Cc: 24012-done, Leo Liu

Stefan Kangas <stefan@marxist.se> writes:

> Dmitry Gutov <dgutov@yandex.ru> writes:
>
>> On 7/17/16 2:04 PM, Leo Liu wrote:
>>> 1. Use the attached file as an example, open it in emacs in ruby-mode
>>> 2. Move point to end of buffer and eval (forward-comment (- (point)))
>>> The last step takes about 0.25 seconds on my MacBook 3 GHz Intel Core
>>> i7. If you double the lines of comments, the time increase by 4 folds.
>>
>> FWIW, it looks fixed in the master branch now.
>>
>> Probably by 14b95587520959c5b54356547a0a69932a9bb480, so no idea what exactly
>> was causing it.
>
> Indeed.  I only see O(n) on current master -- that is, if I use the
> source code from the original report, and double the amount of lines
> by C-x h M-w C-y, the time to evaluate this expression in a buffer
> only doubles:
>
>     (progn (end-of-buffer) (forward-comment (- (point))))
>
> Leo, are you still seeing this issue?  If I don't hear back within a
> couple of weeks, I'll just assume that this has been fixed and close
> this bug.

More information was requested, but none was given within 5 weeks, so
I'm closing this bug.  If this is still an issue, please reopen the
bug report.

Best regards,
Stefan Kangas





^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2019-11-08  3:59 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-07-17 11:04 bug#24012: 25.0.95; forward-comment backwards takes O(n^2) Leo Liu
2016-07-17 12:12 ` Eli Zaretskii
2016-07-18  0:15   ` Leo Liu
2016-07-18  2:36     ` Eli Zaretskii
2016-07-18  3:05       ` Leo Liu
2016-07-18 14:34         ` Eli Zaretskii
2016-07-17 13:39 ` Andreas Röhler
2017-12-25 15:24 ` Dmitry Gutov
2019-09-29  5:15 ` Stefan Kangas
2019-11-08  3:59   ` Stefan Kangas

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).