Can you make this faster?
alejandro david weil
aweil at mail.ru
Sun Jun 27 17:34:50 EDT 2004
On Sun June 27 2004 15:22, Kamilche wrote:
> I have a routine that I really need, but it slows down processing
> significantly. Can you spot any ineffeciencies in the code?
>
> This code makes a critical function of mine run about 7x slower than
> using a prebuilt format string. For maximum flexibility, it would be
> best to calculate the format string using this method, so I'd dearly
> love to keep it.
>
> def fmtstring(args):
> delim = '\0'
> fmt = []
> fmt.append('<')
> for arg in args:
> t = type(arg)
> if t == types.StringType:
> l = len(arg)
> fmt.append(str(l) + 's')
> elif t == types.IntType:
> fmt.append('i')
> elif t == types.LongType:
> fmt.append('q')
> elif t == types.BooleanType:
> fmt.append('c')
> elif t == types.FloatType:
> fmt.append('d')
> else:
> raise Exception("Can't pack argument of type %s!" % t)
> s = ''.join(fmt)
> s = s + '\0'
> return s
I've tried this:
import types
def fmtstring(args):
delim = '\0'
fmt = []
fmt.append('<')
for arg in args:
t = type(arg)
if t == types.StringType:
l = len(arg)
fmt.append(str(l) + 's')
elif t == types.IntType:
fmt.append('i')
elif t == types.LongType:
fmt.append('q')
elif t == types.BooleanType:
fmt.append('c')
elif t == types.FloatType:
fmt.append('d')
else:
raise Exception("Can't pack argument of type %s!" % t)
s = ''.join(fmt)
s = s + '\0'
return s
typedic = {
types.StringType : 's',
types.IntType: 'i',
types.LongType: 'q',
types.BooleanType: 'c',
types.FloatType:'d'}
def myfmtstring(args):
global typedic
f2 = '<'
t = None
for arg in args:
t = type(arg)
if t == types.StringType:
f2 += str(len(arg))
try:
f2 += typedic[t]
except: #check the exception here!
raise Exception("Can't pack argument of type %s!" % t)
return f2+'\0'
if __name__=='__main__':
import unittest
TIMES = 10000
class TestFmtFuncBase(unittest.TestCase):
def setUp(self):
self.what = ['hola','que','tal',324,454,False]
def runFuncOnce(self):
#shouldnt be here!
assert(False)
def runFuncTimes(self, times=TIMES):
for i in xrange(times):
self.runFuncOnce()
class TestFunction1(TestFmtFuncBase):
def runFuncOnce(self):
return fmtstring(self.what)
def testSpeed(self):
"""Run function a lot of times to check its time"""
self.runFuncTimes()
def testValue(self):
"""Check return value"""
print self.runFuncOnce()
class TestFunction2(TestFmtFuncBase):
def runFuncOnce(self):
return myfmtstring(self.what)
def testSpeed(self):
"""Run function a lot of times to check its time"""
self.runFuncTimes()
def testValue(self):
"""Check return value"""
print self.runFuncOnce()
suiteOriginal = unittest.TestSuite()
suiteOriginal.addTest(unittest.makeSuite(TestFunction1))
suiteNew = unittest.TestSuite()
suiteNew.addTest(unittest.makeSuite(TestFunction2))
unittest.TextTestRunner(verbosity=2).run(suiteOriginal)
unittest.TextTestRunner(verbosity=2).run(suiteNew)
And seems to be not faster:
----------------------------------------------------------------------
Run function a lot of times to check its time ... ok
Check return value ... <4s3s3siic
ok
----------------------------------------------------------------------
Ran 2 tests in 0.477s
OK
Run function a lot of times to check its time ... ok
Check return value ... <4s3s3siic
ok
----------------------------------------------------------------------
Ran 2 tests in 0.396s
OK
But, anyway, the problem seems to be the:
f2 += str(len(arg))
line.
If you take it off, you'll see that time reduces to half!
Why? How to fix?
Don't know! :-(
Sorry,
dave
--
+ There is no dark side of the moon really. Matter of fact it's all dark.
More information about the Python-list
mailing list