Re: [Python-Dev] 2.5 slower than 2.4 for some things?

2007-06-13 Thread Neal Norwitz
On 6/13/07, ocean [EMAIL PROTECTED] wrote:
  Meanwhile I tried to replace the parsing I did with Plex by re.Scanner.
 And
  again there is a remarkable speed difference. Again python2.5 is slower:
 
  try:
  from re import Scanner
  except:
  from sre import Scanner
 
  pars = {}
  order = []
  count = 0
 
  def par(scanner,name):
  global count, order, pars
 
  if name in ['caller','e','pi']:
  return name
  if name not in pars.keys():
  pars[name] = ('ns', count)
  order.append(name)
  ret = 'a[%d]'%count
  count += 1
  else:
  ret = 'a[%d]'%(order.index(name))
  return ret
 
  scanner = Scanner([
  (rx, lambda y,x: x),
  (r[a-zA-Z]+\., lambda y,x: x),
  (r[a-z]+\(, lambda y,x: x),
  (r[a-zA-Z_]\w*, par),
  (r\d+\.\d*, lambda y,x: x),
  (r\d+, lambda y,x: x),
  (r\+|-|\*|/, lambda y,x: x),
  (r\s+, None),
  (r\)+, lambda y,x: x),
  (r\(+, lambda y,x: x),
  (r,, lambda y,x: x),
  ])
 
  import profile
  import pstats
 
  def run():
  arg = '+amp*exp(-(x-pos)/fwhm)'
  for i in range(100):
  scanner.scan(arg)
 
  profile.run('run()','profscanner')
  p = pstats.Stats('profscanner')
  p.strip_dirs()
  p.sort_stats('cumulative')
  p.print_stats()

 Well, I tried this script, there was no big difference.
 Python2.4 0.772sec
 Python2.5 0.816sec

 Probably I found one reason comparation for classic style class is slower on
 Python2.5.
 Comparation function instance_compare() calls PyErr_GivenExceptionMatches(),
 and it was just flag operation on 2.4. But on 2.5, probably related to
 introduction of BaseException,
 it checks inherited type tuple. (ie: PyExceptionInstance_Check)

I'm curious about the speed of 2.6 (trunk).  I think this should have
become faster due to the introduction of fast subtype checks (he says
without looking at the code).

n
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] 2.5 slower than 2.4 for some things?

2007-06-13 Thread ocean
  Probably I found one reason comparation for classic style class is
slower on
  Python2.5.
  Comparation function instance_compare() calls
PyErr_GivenExceptionMatches(),
  and it was just flag operation on 2.4. But on 2.5, probably related to
  introduction of BaseException,
  it checks inherited type tuple. (ie: PyExceptionInstance_Check)

 I'm curious about the speed of 2.6 (trunk).  I think this should have
 become faster due to the introduction of fast subtype checks (he says
 without looking at the code).

 n


Yes, I confirmed trunk is faster than 2.5.

///
// Code

import timeit

t = timeit.Timer(
f1  f2
, 
class Foo:
 pass
f1 = Foo()
f2 = Foo()
)

print t.timeit(1)

///
// Result

release-maint24 0.337sec
release-maint25 0.625sec
trunk 0.494sec

//
// Result of plex_test2.py

release-maint24 2.944sec
release-maint25 4.026sec
trunk 3.625sec

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] 2.5 slower than 2.4 for some things?

2007-06-12 Thread Greg Ewing

I've had a report from a user that Plex runs about half
as fast in 2.5 as it did in 2.4. In particular, the
NFA-to-DFA conversion phase, which does a lot of
messing about with dicts representing mappings between
sets of states.

Does anyone in the Ministry for Making Python Blazingly
fast happen to know of some change that might have
pessimised things in this area?

--
Greg
---BeginMessage---
Hi,

I  have been using Plex now for several years and really like it very much!
Recently I switched from python 2.4 to 2.5 and I noticed that the parser runs
significantly slower with 2.5. I hope you do not mind that I attach an example
script and two profiler logs which show the difference. The difference is almost
a factor of 2.   Do you have an idea why that might happen and is there anything
one could do to improve the performance?

Regards, Christian

-- 

Christian Kristukat  ::
Institut fuer Festkoerperphysik, TU Berlin ==
[EMAIL PROTECTED]  ||
Tel. +49-30-20896371  
from Plex import *
from Plex.Traditional import re as regex

class ParseString:
def __init__(self, parse_str):
self.parse_str = parse_str
self.EOF = 0
   
def read(self, size):
if self.EOF:
return ''
else:
self.EOF = 1
return self.parse_str

def reset(self):
self.EOF = 0

class SymParser:
def __init__(self, tok):
self.pstr = ParseString(tok)

self.count = 0
self.varlist = {}
self.dummy = []
self.nvars = 0

self.varfunc = self.setvar

def setvar(self,scanner,name):
if name in ['caller','e','pi']:
return name
if name not in self.varlist:
self.varlist[name] = ['ns',self.nvars]
self.dummy.append(name)
ret = 'a[%d]'%self.nvars
self.nvars += 1
else:
ret = 'a[%d]'%(self.dummy.index(name)+self.count)
return ret

def parse(self):
letter = regex('[A-Za-z_]')
digit = Range(09)
dot = Str(.)
rnumber = (Rep1(digit)+dot+Rep1(digit))|Rep1(digit)
expnumber = Rep1(digit)+dot+Rep1(digit)+Str('e')+(Any('-+')|Empty)+Rep1(digit)
cnumber = (Rep1(digit)+dot+Rep1(digit)+Str('j'))|(Rep1(digit)+Str('j'))
number = rnumber|cnumber|expnumber
x = Str(x)
name = Rep1(letter)|(Rep1(letter)+Rep1(digit)+Rep(letter))
inst_member = (name|Str())|digit)+dot+name
parname = Str(r')+name+Str(r')
func = name+Str(()
op = Any(^+-/*(),)
space = Any( \t\n\r)

lex = Lexicon([
(number, TEXT),
(x, TEXT),
(func, TEXT),
(parname, TEXT),
(inst_member, TEXT),
(name, self.varfunc),
(op, TEXT),
(space, IGNORE),
(AnyChar, IGNORE)
])

parsed = 
scanner = Scanner(lex, self.pstr, pparse)
while 1:
tok = scanner.read()
if tok[0] is None:
break
parsed += tok[0]
self.count += 1

return self.varlist

def sym():
for x in range(10):
a = SymParser('amp*exp(-(x-pos)**2/fwhm)')
a.parse()
print a

def prof_sym():
import profile
import pstats
profile.run('sym()','modelprof')
p = pstats.Stats('modelprof')
p.strip_dirs()
p.sort_stats('cumulative')
p.print_stats()


if __name__ == '__main__':
prof_sym()

__main__.SymParser instance at 0xb7c2d34c
Sat Jun  9 21:45:53 2007modelprof

 106631 function calls (104491 primitive calls) in 1.700 CPU seconds

   Ordered by: cumulative time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
10.0000.0001.7001.700 plex_test2.py:81(sym)
10.0000.0001.7001.700 profile:0(sym())
10.0000.0001.7001.700 string:1(?)
   100.0000.0001.7000.170 plex_test2.py:42(parse)
   100.0000.0001.5600.156 Lexicons.py:113(__init__)
   100.1900.0191.2600.126 DFA.py:13(nfa_to_dfa)
 13500.0700.0000.3100.000 DFA.py:100(old_to_new)
   900.0100.0000.3000.003 
Lexicons.py:158(add_token_to_machine)
   530/900.0300.0000.2700.003 Regexps.py:362(build_machine)
  590/1000.0200.0000.2400.002 Regexps.py:315(build_machine)
 26000.0900.0000.2200.000 DFA.py:50(set_epsilon_closure)
 28000.1700.0000.2200.000 Transitions.py:91(items)
 13500.0500.0000.1900.000 DFA.py:140(make_key)
  2900.0200.0000.1800.001 Regexps.py:384(build_machine)
 13400.1000.0000.1500.000 Machines.py:180(add_transitions)
 26000.0700.0000.1500.000 

Re: [Python-Dev] 2.5 slower than 2.4 for some things?

2007-06-12 Thread ocean
 I've had a report from a user that Plex runs about half
 as fast in 2.5 as it did in 2.4. In particular, the
 NFA-to-DFA conversion phase, which does a lot of
 messing about with dicts representing mappings between
 sets of states.

 Does anyone in the Ministry for Making Python Blazingly
 fast happen to know of some change that might have
 pessimised things in this area?

Hello, I investigated. On my environment, consumed time is

E:\Plex-1.1.5py24 plex_test2.py
0.71065668

E:\Plex-1.1.5py25 plex_test2.py
0.92131335

And after I applied this patch to Plex/Machines, (make `Node' new style
class)

62c62
 class Node:
---
 class Node(object):

E:\Plex-1.1.5py24 plex_test2.py
0.40122888

E:\Plex-1.1.5py25 plex_test2.py
0.350999832153

So, probably hash, comparation mechanizm of old/new style class has changed.
# improved for new style class, worse for old style class. Maybe optimized
for new style class?

Try this for minimum test.

import timeit

init = 
class Class:
 pass
c1 = Class()
c2 = Class()


t1 = timeit.Timer(
c1  c2
, init)

t2 = timeit.Timer(
hash(c1)
hash(c2)
, init)

print t1.timeit(1000)
print t2.timeit(1000)

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] 2.5 slower than 2.4 for some things?

2007-06-12 Thread Greg Ewing
ocean wrote:

 So, probably hash, comparation mechanizm of old/new style class has changed.
 # improved for new style class, worse for old style class. Maybe optimized
 for new style class?

Thanks -- it looks like there's a simple solution that
will make Plex even faster! I'll pass this on to the
OP.

--
Greg
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] 2.5 slower than 2.4 for some things?

2007-06-12 Thread Christian K
ocean wrote:
 I've had a report from a user that Plex runs about half
 as fast in 2.5 as it did in 2.4. In particular, the
 NFA-to-DFA conversion phase, which does a lot of
 messing about with dicts representing mappings between
 sets of states.

That was me.

 Does anyone in the Ministry for Making Python Blazingly
 fast happen to know of some change that might have
 pessimised things in this area?
 
 Hello, I investigated. On my environment, consumed time is
 
 E:\Plex-1.1.5py24 plex_test2.py
 0.71065668
 
 E:\Plex-1.1.5py25 plex_test2.py
 0.92131335
 
 And after I applied this patch to Plex/Machines, (make `Node' new style
 class)
 
 62c62
  class Node:
 ---
 class Node(object):
 
 E:\Plex-1.1.5py24 plex_test2.py
 0.40122888
 
 E:\Plex-1.1.5py25 plex_test2.py
 0.350999832153
 

Nice!.

Meanwhile I tried to replace the parsing I did with Plex by re.Scanner. And
again there is a remarkable speed difference. Again python2.5 is slower:

try:
from re import Scanner
except:
from sre import Scanner

pars = {}
order = []
count = 0

def par(scanner,name):
global count, order, pars

if name in ['caller','e','pi']:
return name
if name not in pars.keys():
pars[name] = ('ns', count)
order.append(name)
ret = 'a[%d]'%count
count += 1
else:
ret = 'a[%d]'%(order.index(name))
return ret

scanner = Scanner([
(rx, lambda y,x: x),
(r[a-zA-Z]+\., lambda y,x: x),
(r[a-z]+\(, lambda y,x: x),
(r[a-zA-Z_]\w*, par),
(r\d+\.\d*, lambda y,x: x),
(r\d+, lambda y,x: x),
(r\+|-|\*|/, lambda y,x: x),
(r\s+, None),
(r\)+, lambda y,x: x),
(r\(+, lambda y,x: x),
(r,, lambda y,x: x),
])

import profile
import pstats

def run():
arg = '+amp*exp(-(x-pos)/fwhm)'
for i in range(100):
scanner.scan(arg)

profile.run('run()','profscanner')
p = pstats.Stats('profscanner')
p.strip_dirs()
p.sort_stats('cumulative')
p.print_stats()


Christian

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com