Hi All!
On Jun 3, 4:27 pm, [email protected] wrote:
...
> A partial solution for 3) might be to pre-compile certain useful
> regular expressions, and store them as an attribute of the interface
> instance. In that way, it would not be needed to do the 83
> compilations of regular expressions over and over again.
I think I found where all the regular expression compilations occur:
It is the method '_execute_line' of the gap interface. After starting
sage, do:
sage: gap._start()
sage: prun gap._execute_line('b:=1;\n')
ncalls tottime percall cumtime percall filename:lineno
(function)
8 0.000 0.000 0.001 0.000 pexpect.py:914
(expect_list)
8 0.000 0.000 0.001 0.000 pexpect.py:815
(compile_pattern_list)
83 0.000 0.000 0.001 0.000 re.py:227(_compile)
83 0.000 0.000 0.001 0.000 re.py:186(compile)
...
Interestingly, running it a second time yields:
sage: prun gap._execute_line('b:=1;\n')
ncalls tottime percall cumtime percall filename:lineno
(function)
16 0.001 0.000 0.003 0.000 pexpect.py:815
(compile_pattern_list)
16 0.001 0.000 0.002 0.000 pexpect.py:914
(expect_list)
211 0.001 0.000 0.001 0.000 re.py:227(_compile)
211 0.001 0.000 0.002 0.000 re.py:186(compile)
Indeed, Gap._execute_line (in sage/interfaces/gap.py) calls "expect"
in a loop. This should be avoided, according to the documentation of
compile_pattern_list (in SAGE_ROOT/local/lib/python2.5/site-packages/
pexpect.py):
"""
...
This is used by expect() when calling expect_list().
Thus expect() is nothing more than::
cpl = self.compile_pattern_list(pl)
return self.expect_list(clp, timeout)
If you are using expect() within a loop it may be more
efficient to compile the patterns first and then call
expect_list().
This avoid calls in a loop to compile_pattern_list():
cpl = self.compile_pattern_list(my_pattern)
while some_condition:
...
i = self.expect_list(clp, timeout)
...
"""
(seems that they have a misprint: cpl and clp should be the same.
So, some improvement seems possible. We have two *different* patterns
occuring in the while-loop of Gap._execute_line:
First (l. 588):
E.expect(['@p\d+\.','@@','@[A-Z]','@[123456!"#$%&][^+]*\
+',
'@e','@c','@f','@h','@i','@m','@n','@r','@s\d','@w.*\+',
'@x','@z'])
then (l. 619):
E.expect('@J')
These two patterns could be computed *once* when creating a gap
interface instance, stored, and then E.expect_list should be called
with the stored patterns.
Note that the Singular interface avoids this bottle neck. Here, we
have a method _eval_line (apparently supposed to have a similar
purpose as gap._execute_line):
sage: prun singular._eval_line('int b=1;\n')
ncalls tottime percall cumtime percall filename:lineno
(function)
1 0.000 0.000 0.000 0.000 expect.py:632
(_eval_line)
1 0.000 0.000 0.000 0.000 pexpect.py:914
(expect_list)
1 0.000 0.000 0.000 0.000 pexpect.py:498
(read_nonblocking)
2 0.000 0.000 0.000 0.000 pexpect.py:656(send)
1 0.000 0.000 0.000 0.000 <string>:1(<module>)
2 0.000 0.000 0.000 0.000 {posix.write}
1 0.000 0.000 0.000 0.000 {select.select}
1 0.000 0.000 0.000 0.000 pexpect.py:815
(compile_pattern_list)
Indeed, there is no loop in Singular._eval_line.
So, if nobody tells me that the above is complete nonsense, I will try
and improve Gap._execute_line.
Cheers,
Simon
--~--~---------~--~----~------------~-------~--~----~
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/sage-support
URLs: http://www.sagemath.org
-~----------~----~----~----~------~----~------~--~---