Re: Dramatic slowdown -ping Rob
- Posted by Robert Craig <rds at RapidEuphoria.com> Nov 29, 2004
- 603 views
As promised, I looked into the performance issue raised by Pete Lomax a while back. I don't think there is any bug in Euphoria itself (ref counts etc.). I rather think WATCOM's storage allocator for DOS has some very quirky behavior. In exw.exe I don't use the WATCOM allocator, I use Microsoft's. I earlier reported no problem with ex.exe for 2.5, but I think I must have been using exw.exe for 2.5. exw runs the code below very fast regardless of the size of the sequences. People noticed a big slowdown with ex.exe when moving from 27 to 28. I believe that's because I allocate 50% more space when the size becomes 28. For speed in handling small sequences, I map to a set of standard memory block sizes: 16, 24, 32, 48, 64, 96, 128 bytes, 192 bytes, 256 etc. I think 27 would need 128, while 28 would need 192. However, strangely enough, when the size is increased from 28 to 100, it runs really fast, even though more processing is being done by Euphoria. I also noticed that when it runs slow, it actually runs fast to start with, and then at a certain point it starts taking longer and longer to allocate a block. I downloaded the WATCOM source, but I couldn't really understand how the allocator works. From the comments it did seem like it was fairly complex, with a lot of special cases, and multiple heaps, and there was special code added to deal with worst case situations. Below is Pete's code with a lot of mods to get better information.
-- Time profile based on 167 samples. -- Left margin shows the percentage of total execution time -- consumed by the statement(s) on that line. | |constant START = time() |constant INNER=28 --27 good, 28 bad, 50 bad, 100 good, why? |sequence table |table=repeat(repeat(0,INNER),1024) |integer used |used=1 |sequence t1, t2 |atom t |t = time() | |for i=1 to 45000 do | used+=1 0.60 | if remainder(i,3000) = 0 then 0.60 | printf(1, "%d: %.2f\n", {i, time()-t}) | t = time() | end if 0.60 | if used>length(table) then | t1 = repeat(0, INNER) | t2 = repeat(t1, 1024) 2.40 | table &= t2 | end if 95.81 | table[used][1]=99 -- here's where almost all | -- the 28-long sequence blocks are allocated |end for | |printf(1, "Elapsed time: %f\n", time() - START)
Regards, Rob Craig Rapid Deployment Software http://www.RapidEuphoria.com