not sure how more we can help without looking into the code
On Mon, Mar 17, 2014 at 6:05 PM, Martin Koch <m...@issuu.com> wrote: > Thanks :) > > /Martin > > >> On 17/03/2014, at 16.41, Maciej Fijalkowski <fij...@gmail.com> wrote: >> >> ok. >> >> so as you can probably see, the max is not that big, which means the >> GC is really incremental. What happens is you get tons of garbage that >> survives minor collection every now and then. I don't exactly know >> why, but you should look what objects can potentially survive for too >> long. >> >>> On Mon, Mar 17, 2014 at 5:37 PM, Martin Koch <m...@issuu.com> wrote: >>> Ah - it just occured to me that the first runs may be slow anyway: Since we >>> take the average of the last 100 runs as the benchmark, then the first 100 >>> runs are not classified as slow. Indeed, the first three runs with many >>> collections are in the first 100 runs. >>> >>> >>>> On Mon, Mar 17, 2014 at 4:35 PM, Martin Koch <m...@issuu.com> wrote: >>>> >>>> Here are the total and max times in millions of units; 30000 units is >>>> approximately 13 seconds. I have extracted the runs where there are many >>>> gc-collect-steps. These are in execution order, so the first runs with many >>>> gc-collect-steps aren't slow. >>>> >>>> Totals: gc-minor:418 gc-minor-walkroots:0 gc-collect-step:28797 Max: >>>> gc-minor:10 gc-collect-step:247 >>>> Totals: gc-minor:562 gc-minor-walkroots:0 gc-collect-step:30282 Max: >>>> gc-minor:10 gc-collect-step:245 >>>> Totals: gc-minor:434 gc-minor-walkroots:0 gc-collect-step:31040 Max: >>>> gc-minor:11 gc-collect-step:244 >>>> Totals: gc-minor:417 slow:1 gc-minor-walkroots:0 gc-collect-step:31270 >>>> Max: gc-minor:17 gc-collect-step:244 >>>> Totals: gc-minor:435 slow:1 gc-minor-walkroots:0 gc-collect-step:30365 >>>> Max: gc-minor:11 gc-collect-step:248 >>>> Totals: gc-minor:389 slow:1 gc-minor-walkroots:0 gc-collect-step:31235 >>>> Max: gc-minor:8 gc-collect-step:299 >>>> Totals: gc-minor:434 slow:1 gc-minor-walkroots:0 gc-collect-step:31124 >>>> Max: gc-minor:11 gc-collect-step:246 >>>> Totals: gc-minor:386 slow:1 gc-minor-walkroots:0 gc-collect-step:30541 >>>> Max: gc-minor:8 gc-collect-step:244 >>>> Totals: gc-minor:410 slow:1 gc-minor-walkroots:0 gc-collect-step:31427 >>>> Max: gc-minor:36 gc-collect-step:248 >>>> Totals: gc-minor:390 slow:1 gc-minor-walkroots:0 gc-collect-step:30743 >>>> Max: gc-minor:8 gc-collect-step:244 >>>> Totals: gc-minor:380 slow:1 gc-minor-walkroots:0 gc-collect-step:30207 >>>> Max: gc-minor:8 gc-collect-step:245 >>>> Totals: gc-minor:387 slow:1 gc-minor-walkroots:0 gc-collect-step:30837 >>>> Max: gc-minor:8 gc-collect-step:244 >>>> Totals: gc-minor:412 slow:1 gc-minor-walkroots:0 gc-collect-step:30898 >>>> Max: gc-minor:38 gc-collect-step:244 >>>> Totals: gc-minor:415 slow:1 gc-minor-walkroots:0 gc-collect-step:30407 >>>> Max: gc-minor:23 gc-collect-step:245 >>>> Totals: gc-minor:380 slow:1 gc-minor-walkroots:0 gc-collect-step:30591 >>>> Max: gc-minor:8 gc-collect-step:246 >>>> Totals: gc-minor:387 slow:1 gc-minor-walkroots:0 gc-collect-step:31193 >>>> Max: gc-minor:9 gc-collect-step:244 >>>> Totals: gc-minor:379 slow:1 gc-minor-walkroots:0 gc-collect-step:30026 >>>> Max: gc-minor:8 gc-collect-step:246 >>>> Totals: gc-minor:388 slow:1 gc-minor-walkroots:0 gc-collect-step:31179 >>>> Max: gc-minor:8 gc-collect-step:248 >>>> Totals: gc-minor:378 slow:1 gc-minor-walkroots:0 gc-collect-step:30674 >>>> Max: gc-minor:8 gc-collect-step:250 >>>> Totals: gc-minor:385 slow:1 gc-minor-walkroots:0 gc-collect-step:30413 >>>> Max: gc-minor:8 gc-collect-step:245 >>>> Totals: gc-minor:915 slow:1 gc-minor-walkroots:0 gc-collect-step:30830 >>>> Max: gc-minor:543 gc-collect-step:244 >>>> Totals: gc-minor:405 slow:1 gc-minor-walkroots:0 gc-collect-step:31153 >>>> Max: gc-minor:20 gc-collect-step:246 >>>> Totals: gc-minor:408 slow:1 gc-minor-walkroots:0 gc-collect-step:29815 >>>> Max: gc-minor:25 gc-collect-step:245 >>>> >>>> Thanks, >>>> /Martin >>>> >>>> >>>>> On Mon, Mar 17, 2014 at 3:24 PM, Martin Koch <m...@issuu.com> wrote: >>>>> >>>>> Ah. I had misunderstood. I'll get back to you on that :) thanks >>>>> >>>>> /Martin >>>>> >>>>> >>>>>> On 17/03/2014, at 15.21, Maciej Fijalkowski <fij...@gmail.com> wrote: >>>>>> >>>>>> eh, this is not what I need >>>>>> >>>>>> I need a max of TIME it took for a gc-minor and the TOTAL time it took >>>>>> for a gc-minor (per query) (ideally same for gc-walkroots and >>>>>> gc-collect-step) >>>>>> >>>>>>> On Mon, Mar 17, 2014 at 4:19 PM, Martin Koch <m...@issuu.com> wrote: >>>>>>> Here are the collated results of running each query. For each run, I >>>>>>> count >>>>>>> how many of each of the pypy debug lines i get. I.e. there were 668 >>>>>>> runs >>>>>>> that printed 58 loglines that contain "{gc-minor" which was eventually >>>>>>> followed by "gc-minor}". I have also counted if the query was slow; >>>>>>> interestingly, not all the queries with many gc-minors were slow (but >>>>>>> all >>>>>>> slow queries had a gc-minor). >>>>>>> >>>>>>> Please let me know if this is unclear :) >>>>>>> >>>>>>> 668 gc-minor:58 gc-minor-walkroots:58 >>>>>>> 10 gc-minor:58 gc-minor-walkroots:58 gc-collect-step:5 >>>>>>> 140 gc-minor:59 gc-minor-walkroots:59 >>>>>>> 1 gc-minor:8441 gc-minor-walkroots:8441 gc-collect-step:8403 >>>>>>> 1 gc-minor:9300 gc-minor-walkroots:9300 gc-collect-step:9249 >>>>>>> 9 gc-minor:9643 slow:1 gc-minor-walkroots:9643 >>>>>>> gc-collect-step:9589 >>>>>>> 1 gc-minor:9644 slow:1 gc-minor-walkroots:9644 >>>>>>> gc-collect-step:9590 >>>>>>> 10 gc-minor:9647 slow:1 gc-minor-walkroots:9647 >>>>>>> gc-collect-step:9609 >>>>>>> 1 gc-minor:9663 gc-minor-walkroots:9663 gc-collect-step:9614 >>>>>>> 1 jit-backend-dump:5 gc-minor:58 gc-minor-walkroots:58 >>>>>>> 1 jit-log-compiling-loop:1 gc-collect-step:8991 >>>>>>> jit-backend-dump:78 >>>>>>> jit-backend:3 jit-log-noopt-loop:6 jit-log-virtualstate:3 >>>>>>> gc-minor:9030 >>>>>>> jit-tracing:3 gc-minor-walkroots:9030 jit-optimize:6 >>>>>>> jit-log-short-preamble:2 jit-backend-addr:3 jit-log-opt-loop:1 >>>>>>> jit-mem-looptoken-alloc:3 jit-abort:3 jit-log-rewritten-bridge:2 >>>>>>> jit-log-rewritten-loop:1 jit-log-opt-bridge:2 >>>>>>> jit-log-compiling-bridge:2 >>>>>>> jit-resume:84 >>>>>>> 1 jit-log-compiling-loop:1 jit-backend-dump:13 jit-backend:1 >>>>>>> jit-log-noopt-loop:2 gc-minor:60 jit-tracing:1 gc-minor-walkroots:60 >>>>>>> jit-optimize:2 jit-log-short-preamble:1 jit-backend-addr:1 >>>>>>> jit-log-opt-loop:1 jit-mem-looptoken-alloc:1 jit-log-rewritten-loop:1 >>>>>>> jit-resume:14 >>>>>>> 1 jit-log-compiling-loop:1 jit-backend-dump:73 jit-backend:3 >>>>>>> jit-log-noopt-loop:6 jit-log-virtualstate:3 gc-minor:60 jit-tracing:3 >>>>>>> gc-minor-walkroots:60 jit-optimize:6 jit-log-short-preamble:2 >>>>>>> jit-backend-addr:3 jit-log-opt-loop:1 jit-mem-looptoken-alloc:3 >>>>>>> jit-abort:3 >>>>>>> jit-log-rewritten-bridge:2 jit-log-rewritten-loop:1 >>>>>>> jit-log-opt-bridge:2 >>>>>>> jit-log-compiling-bridge:2 jit-resume:84 >>>>>>> 2 jit-log-compiling-loop:1 jit-backend-dump:78 jit-backend:3 >>>>>>> jit-log-noopt-loop:6 jit-log-virtualstate:3 gc-minor:61 jit-tracing:3 >>>>>>> gc-minor-walkroots:61 jit-optimize:6 jit-log-short-preamble:2 >>>>>>> jit-backend-addr:3 jit-log-opt-loop:1 jit-mem-looptoken-alloc:3 >>>>>>> jit-abort:3 >>>>>>> jit-log-rewritten-bridge:2 jit-log-rewritten-loop:1 >>>>>>> jit-log-opt-bridge:2 >>>>>>> jit-log-compiling-bridge:2 jit-resume:84 >>>>>>> 1 jit-log-short-preamble:2 jit-log-compiling-loop:2 >>>>>>> jit-backend-dump:92 jit-log-noopt-loop:7 jit-log-virtualstate:3 >>>>>>> gc-minor:61 >>>>>>> jit-tracing:4 gc-minor-walkroots:61 jit-optimize:7 jit-backend:4 >>>>>>> jit-backend-addr:4 jit-log-opt-loop:2 jit-mem-looptoken-alloc:4 >>>>>>> jit-abort:3 >>>>>>> jit-log-rewritten-bridge:2 jit-log-rewritten-loop:2 >>>>>>> jit-log-opt-bridge:2 >>>>>>> jit-log-compiling-bridge:2 jit-resume:104 >>>>>>> >>>>>>> >>>>>>> Thanks, >>>>>>> /Martin >>>>>>> >>>>>>> >>>>>>> >>>>>>> On Mon, Mar 17, 2014 at 2:23 PM, Maciej Fijalkowski <fij...@gmail.com> >>>>>>> wrote: >>>>>>>> >>>>>>>> On Mon, Mar 17, 2014 at 3:20 PM, Maciej Fijalkowski >>>>>>>> <fij...@gmail.com> >>>>>>>> wrote: >>>>>>>>> are you *sure* it's the walkroots that take that long and not >>>>>>>>> something else (like gc-minor)? More of those mean that you allocate >>>>>>>>> a >>>>>>>>> lot more surviving objects. Can you do two things: >>>>>>>>> >>>>>>>>> a) take a max of gc-minor (and gc-minor-stackwalk), per request >>>>>>>>> b) take the sum of those >>>>>>>>> >>>>>>>>> and plot them >>>>>>>> >>>>>>>> ^^^ or just paste the results actually >>>>>>>> >>>>>>>>> >>>>>>>>>> On Mon, Mar 17, 2014 at 3:18 PM, Martin Koch <m...@issuu.com> wrote: >>>>>>>>>> Well, then it works out to around 2.5GHz, which seems reasonable. >>>>>>>>>> But >>>>>>>>>> it >>>>>>>>>> doesn't alter the conclusion from the previous email: The slow >>>>>>>>>> queries >>>>>>>>>> then >>>>>>>>>> all have a duration around 34*10^9 units, 'normal' queries 1*10^9 >>>>>>>>>> units, or >>>>>>>>>> .4 seconds at this conversion. Also, the log shows that a slow >>>>>>>>>> query >>>>>>>>>> performs many more gc-minor operations than a 'normal' one: 9600 >>>>>>>>>> gc-collect-step/gc-minor/gc-minor-walkroots operations vs 58. >>>>>>>>>> >>>>>>>>>> So the question becomes: Why do we get this large spike in >>>>>>>>>> gc-minor-walkroots, and, in particular, is there any way to avoid >>>>>>>>>> it :) >>>>>>>>>> ? >>>>>>>>>> >>>>>>>>>> Thanks, >>>>>>>>>> /Martin >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> On Mon, Mar 17, 2014 at 1:53 PM, Maciej Fijalkowski >>>>>>>>>> <fij...@gmail.com> >>>>>>>>>> wrote: >>>>>>>>>>> >>>>>>>>>>> I think it's the cycles of your CPU >>>>>>>>>>> >>>>>>>>>>>> On Mon, Mar 17, 2014 at 2:48 PM, Martin Koch <m...@issuu.com> >>>>>>>>>>>> wrote: >>>>>>>>>>>> What is the unit? Perhaps I'm being thick here, but I can't >>>>>>>>>>>> correlate it >>>>>>>>>>>> with seconds (which the program does print out). Slow runs are >>>>>>>>>>>> around 13 >>>>>>>>>>>> seconds, but are around 34*10^9(dec), 0x800000000 timestamp units >>>>>>>>>>>> (e.g. >>>>>>>>>>>> from >>>>>>>>>>>> 0x2b994c9d31889c to 0x2b9944ab8c4f49). >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> On Mon, Mar 17, 2014 at 12:09 PM, Maciej Fijalkowski >>>>>>>>>>>> <fij...@gmail.com> >>>>>>>>>>>> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>> The number of lines is nonsense. This is a timestamp in hex. >>>>>>>>>>>>> >>>>>>>>>>>>> On Mon, Mar 17, 2014 at 12:46 PM, Martin Koch <m...@issuu.com> >>>>>>>>>>>>> wrote: >>>>>>>>>>>>>> Based On Maciej's suggestion, I tried the following >>>>>>>>>>>>>> >>>>>>>>>>>>>> PYPYLOG=- pypy mem.py 10000000 > out >>>>>>>>>>>>>> >>>>>>>>>>>>>> This generates a logfile which looks something like this >>>>>>>>>>>>>> >>>>>>>>>>>>>> start--> >>>>>>>>>>>>>> [2b99f1981b527e] {gc-minor >>>>>>>>>>>>>> [2b99f1981ba680] {gc-minor-walkroots >>>>>>>>>>>>>> [2b99f1981c2e02] gc-minor-walkroots} >>>>>>>>>>>>>> [2b99f19890d750] gc-minor} >>>>>>>>>>>>>> [snip] >>>>>>>>>>>>>> ... >>>>>>>>>>>>>> <--stop >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> It turns out that the culprit is a lot of MINOR collections. >>>>>>>>>>>>>> >>>>>>>>>>>>>> I base this on the following observations: >>>>>>>>>>>>>> >>>>>>>>>>>>>> I can't understand the format of the timestamp on each logline >>>>>>>>>>>>>> (the >>>>>>>>>>>>>> "[2b99f1981b527e]"). From what I can see in the code, this >>>>>>>>>>>>>> should >>>>>>>>>>>>>> be >>>>>>>>>>>>>> output >>>>>>>>>>>>>> from time.clock(), but that doesn't return a number like that >>>>>>>>>>>>>> when I >>>>>>>>>>>>>> run >>>>>>>>>>>>>> pypy interactively >>>>>>>>>>>>>> Instead, I count the number of debug lines between start--> and >>>>>>>>>>>>>> the >>>>>>>>>>>>>> corresponding <--stop. >>>>>>>>>>>>>> Most runs have a few hundred lines of output between start/stop >>>>>>>>>>>>>> All slow runs have very close to 57800 lines out output between >>>>>>>>>>>>>> start/stop >>>>>>>>>>>>>> One such sample does 9609 gc-collect-step operations, 9647 >>>>>>>>>>>>>> gc-minor >>>>>>>>>>>>>> operations, and 9647 gc-minor-walkroots operations. >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> Thanks, >>>>>>>>>>>>>> /Martin >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> On Mon, Mar 17, 2014 at 8:21 AM, Maciej Fijalkowski >>>>>>>>>>>>>> <fij...@gmail.com> >>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> there is an environment variable PYPYLOG=gc:- (where - is >>>>>>>>>>>>>>> stdout) >>>>>>>>>>>>>>> which will do that for you btw. >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> maybe you can find out what's that using profiling or >>>>>>>>>>>>>>> valgrind? >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> On Sun, Mar 16, 2014 at 11:34 PM, Martin Koch <m...@issuu.com> >>>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>>>> I have tried getting the pypy source and building my own >>>>>>>>>>>>>>>> version >>>>>>>>>>>>>>>> of >>>>>>>>>>>>>>>> pypy. I >>>>>>>>>>>>>>>> have modified >>>>>>>>>>>>>>>> rpython/memory/gc/incminimark.py:major_collection_step() >>>>>>>>>>>>>>>> to >>>>>>>>>>>>>>>> print out when it starts and when it stops. Apparently, the >>>>>>>>>>>>>>>> slow >>>>>>>>>>>>>>>> queries >>>>>>>>>>>>>>>> do >>>>>>>>>>>>>>>> NOT occur during major_collection_step; at least, I have not >>>>>>>>>>>>>>>> observed >>>>>>>>>>>>>>>> major >>>>>>>>>>>>>>>> step output during a query execution. So, apparently, >>>>>>>>>>>>>>>> something >>>>>>>>>>>>>>>> else >>>>>>>>>>>>>>>> is >>>>>>>>>>>>>>>> blocking. This could be another aspect of the GC, but it >>>>>>>>>>>>>>>> could >>>>>>>>>>>>>>>> also >>>>>>>>>>>>>>>> be >>>>>>>>>>>>>>>> anything else. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Just to be sure, I have tried running the same application in >>>>>>>>>>>>>>>> python >>>>>>>>>>>>>>>> with >>>>>>>>>>>>>>>> garbage collection disabled. I don't see the problem there, >>>>>>>>>>>>>>>> so >>>>>>>>>>>>>>>> it >>>>>>>>>>>>>>>> is >>>>>>>>>>>>>>>> somehow >>>>>>>>>>>>>>>> related to either GC or the runtime somehow. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Cheers, >>>>>>>>>>>>>>>> /Martin >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> On Fri, Mar 14, 2014 at 4:19 PM, Martin Koch <m...@issuu.com> >>>>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> We have hacked up a small sample that seems to exhibit the >>>>>>>>>>>>>>>>> same >>>>>>>>>>>>>>>>> issue. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> We basically generate a linked list of objects. To increase >>>>>>>>>>>>>>>>> connectedness, >>>>>>>>>>>>>>>>> elements in the list hold references (dummy_links) to 10 >>>>>>>>>>>>>>>>> randomly >>>>>>>>>>>>>>>>> chosen >>>>>>>>>>>>>>>>> previous elements in the list. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> We then time a function that traverses 50000 elements from >>>>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>>> list >>>>>>>>>>>>>>>>> from a >>>>>>>>>>>>>>>>> random start point. If the traversal reaches the end of the >>>>>>>>>>>>>>>>> list, >>>>>>>>>>>>>>>>> we >>>>>>>>>>>>>>>>> instead >>>>>>>>>>>>>>>>> traverse one of the dummy links. Thus, exactly 50K elements >>>>>>>>>>>>>>>>> are >>>>>>>>>>>>>>>>> traversed >>>>>>>>>>>>>>>>> every time. To generate some garbage, we build a list >>>>>>>>>>>>>>>>> holding >>>>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>>> traversed >>>>>>>>>>>>>>>>> elements and a dummy list of characters. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Timings for the last 100 runs are stored in a circular >>>>>>>>>>>>>>>>> buffer. If >>>>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>>> elapsed time for the last run is more than twice the average >>>>>>>>>>>>>>>>> time, >>>>>>>>>>>>>>>>> we >>>>>>>>>>>>>>>>> print >>>>>>>>>>>>>>>>> out a line with the elapsed time, the threshold, and the 90% >>>>>>>>>>>>>>>>> runtime >>>>>>>>>>>>>>>>> (we >>>>>>>>>>>>>>>>> would like to see that the mean runtime does not increase >>>>>>>>>>>>>>>>> with >>>>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>>> number of >>>>>>>>>>>>>>>>> elements in the list, but that the max time does increase >>>>>>>>>>>>>>>>> (linearly >>>>>>>>>>>>>>>>> with the >>>>>>>>>>>>>>>>> number of object, i guess); traversing 50K elements should >>>>>>>>>>>>>>>>> be >>>>>>>>>>>>>>>>> independent of >>>>>>>>>>>>>>>>> the memory size). >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> We have tried monitoring memory consumption by external >>>>>>>>>>>>>>>>> inspection, >>>>>>>>>>>>>>>>> but >>>>>>>>>>>>>>>>> cannot consistently verify that memory is deallocated at the >>>>>>>>>>>>>>>>> same >>>>>>>>>>>>>>>>> time >>>>>>>>>>>>>>>>> that >>>>>>>>>>>>>>>>> we see slow requests. Perhaps the pypy runtime doesn't >>>>>>>>>>>>>>>>> always >>>>>>>>>>>>>>>>> return >>>>>>>>>>>>>>>>> freed >>>>>>>>>>>>>>>>> pages back to the OS? >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Using top, we observe that 10M elements allocates around >>>>>>>>>>>>>>>>> 17GB >>>>>>>>>>>>>>>>> after >>>>>>>>>>>>>>>>> building, 20M elements 26GB, 30M elements 28GB (and grows to >>>>>>>>>>>>>>>>> 35GB >>>>>>>>>>>>>>>>> shortly >>>>>>>>>>>>>>>>> after building). >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Here is output from a few runs with different number of >>>>>>>>>>>>>>>>> elements: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> pypy mem.py 10000000 >>>>>>>>>>>>>>>>> start build >>>>>>>>>>>>>>>>> end build 84.142424 >>>>>>>>>>>>>>>>> that took a long time elapsed: 13.230586 slow_threshold: >>>>>>>>>>>>>>>>> 1.495401 >>>>>>>>>>>>>>>>> 90th_quantile_runtime: 0.421558 >>>>>>>>>>>>>>>>> that took a long time elapsed: 13.016531 slow_threshold: >>>>>>>>>>>>>>>>> 1.488160 >>>>>>>>>>>>>>>>> 90th_quantile_runtime: 0.423441 >>>>>>>>>>>>>>>>> that took a long time elapsed: 13.032537 slow_threshold: >>>>>>>>>>>>>>>>> 1.474563 >>>>>>>>>>>>>>>>> 90th_quantile_runtime: 0.419817 >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> pypy mem.py 20000000 >>>>>>>>>>>>>>>>> start build >>>>>>>>>>>>>>>>> end build 180.823105 >>>>>>>>>>>>>>>>> that took a long time elapsed: 27.346064 slow_threshold: >>>>>>>>>>>>>>>>> 2.295146 >>>>>>>>>>>>>>>>> 90th_quantile_runtime: 0.434726 >>>>>>>>>>>>>>>>> that took a long time elapsed: 26.028852 slow_threshold: >>>>>>>>>>>>>>>>> 2.283927 >>>>>>>>>>>>>>>>> 90th_quantile_runtime: 0.374190 >>>>>>>>>>>>>>>>> that took a long time elapsed: 25.432279 slow_threshold: >>>>>>>>>>>>>>>>> 2.279631 >>>>>>>>>>>>>>>>> 90th_quantile_runtime: 0.371502 >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> pypy mem.py 30000000 >>>>>>>>>>>>>>>>> start build >>>>>>>>>>>>>>>>> end build 276.217811 >>>>>>>>>>>>>>>>> that took a long time elapsed: 40.993855 slow_threshold: >>>>>>>>>>>>>>>>> 3.188464 >>>>>>>>>>>>>>>>> 90th_quantile_runtime: 0.459891 >>>>>>>>>>>>>>>>> that took a long time elapsed: 41.693553 slow_threshold: >>>>>>>>>>>>>>>>> 3.183003 >>>>>>>>>>>>>>>>> 90th_quantile_runtime: 0.393654 >>>>>>>>>>>>>>>>> that took a long time elapsed: 39.679769 slow_threshold: >>>>>>>>>>>>>>>>> 3.190782 >>>>>>>>>>>>>>>>> 90th_quantile_runtime: 0.393677 >>>>>>>>>>>>>>>>> that took a long time elapsed: 43.573411 slow_threshold: >>>>>>>>>>>>>>>>> 3.239637 >>>>>>>>>>>>>>>>> 90th_quantile_runtime: 0.393654 >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Code below >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> -------------------------------------------------------------- >>>>>>>>>>>>>>>>> import time >>>>>>>>>>>>>>>>> from random import randint, choice >>>>>>>>>>>>>>>>> import sys >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> allElems = {} >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> class Node: >>>>>>>>>>>>>>>>> def __init__(self, v_): >>>>>>>>>>>>>>>>> self.v = v_ >>>>>>>>>>>>>>>>> self.next = None >>>>>>>>>>>>>>>>> self.dummy_data = [randint(0,100) >>>>>>>>>>>>>>>>> for _ in xrange(randint(50,100))] >>>>>>>>>>>>>>>>> allElems[self.v] = self >>>>>>>>>>>>>>>>> if self.v > 0: >>>>>>>>>>>>>>>>> self.dummy_links = [allElems[randint(0, >>>>>>>>>>>>>>>>> self.v-1)] >>>>>>>>>>>>>>>>> for _ >>>>>>>>>>>>>>>>> in >>>>>>>>>>>>>>>>> xrange(10)] >>>>>>>>>>>>>>>>> else: >>>>>>>>>>>>>>>>> self.dummy_links = [self] >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> def set_next(self, l): >>>>>>>>>>>>>>>>> self.next = l >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> def follow(node): >>>>>>>>>>>>>>>>> acc = [] >>>>>>>>>>>>>>>>> count = 0 >>>>>>>>>>>>>>>>> cur = node >>>>>>>>>>>>>>>>> assert node.v is not None >>>>>>>>>>>>>>>>> assert cur is not None >>>>>>>>>>>>>>>>> while count < 50000: >>>>>>>>>>>>>>>>> # return a value; generate some garbage >>>>>>>>>>>>>>>>> acc.append((cur.v, >>>>>>>>>>>>>>>>> [choice("abcdefghijklmnopqrstuvwxyz") >>>>>>>>>>>>>>>>> for >>>>>>>>>>>>>>>>> x >>>>>>>>>>>>>>>>> in >>>>>>>>>>>>>>>>> xrange(100)])) >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> # if we have reached the end, chose a random link >>>>>>>>>>>>>>>>> cur = choice(cur.dummy_links) if cur.next is None >>>>>>>>>>>>>>>>> else >>>>>>>>>>>>>>>>> cur.next >>>>>>>>>>>>>>>>> count += 1 >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> return acc >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> def build(num_elems): >>>>>>>>>>>>>>>>> start = time.time() >>>>>>>>>>>>>>>>> print "start build" >>>>>>>>>>>>>>>>> root = Node(0) >>>>>>>>>>>>>>>>> cur = root >>>>>>>>>>>>>>>>> for x in xrange(1, num_elems): >>>>>>>>>>>>>>>>> e = Node(x) >>>>>>>>>>>>>>>>> cur.next = e >>>>>>>>>>>>>>>>> cur = e >>>>>>>>>>>>>>>>> print "end build %f" % (time.time() - start) >>>>>>>>>>>>>>>>> return root >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> num_timings = 100 >>>>>>>>>>>>>>>>> if __name__ == "__main__": >>>>>>>>>>>>>>>>> num_elems = int(sys.argv[1]) >>>>>>>>>>>>>>>>> build(num_elems) >>>>>>>>>>>>>>>>> total = 0 >>>>>>>>>>>>>>>>> timings = [0.0] * num_timings # run times for the last >>>>>>>>>>>>>>>>> num_timings >>>>>>>>>>>>>>>>> runs >>>>>>>>>>>>>>>>> i = 0 >>>>>>>>>>>>>>>>> beginning = time.time() >>>>>>>>>>>>>>>>> while time.time() - beginning < 600: >>>>>>>>>>>>>>>>> start = time.time() >>>>>>>>>>>>>>>>> elem = allElems[randint(0, num_elems - 1)] >>>>>>>>>>>>>>>>> assert(elem is not None) >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> lst = follow(elem) >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> total += choice(lst)[0] # use the return value for >>>>>>>>>>>>>>>>> something >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> end = time.time() >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> elapsed = end-start >>>>>>>>>>>>>>>>> timings[i % num_timings] = elapsed >>>>>>>>>>>>>>>>> if (i > num_timings): >>>>>>>>>>>>>>>>> slow_time = 2 * sum(timings)/num_timings # slow >>>>>>>>>>>>>>>>> defined >>>>>>>>>>>>>>>>> as >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> 2*avg run time >>>>>>>>>>>>>>>>> if (elapsed > slow_time): >>>>>>>>>>>>>>>>> print "that took a long time elapsed: %f >>>>>>>>>>>>>>>>> slow_threshold: >>>>>>>>>>>>>>>>> %f 90th_quantile_runtime: %f" % \ >>>>>>>>>>>>>>>>> (elapsed, slow_time, >>>>>>>>>>>>>>>>> sorted(timings)[int(num_timings*.9)]) >>>>>>>>>>>>>>>>> i += 1 >>>>>>>>>>>>>>>>> print total >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> On Thu, Mar 13, 2014 at 7:45 PM, Maciej Fijalkowski >>>>>>>>>>>>>>>>> <fij...@gmail.com> >>>>>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> On Thu, Mar 13, 2014 at 1:45 PM, Martin Koch >>>>>>>>>>>>>>>>>> <m...@issuu.com> >>>>>>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>>>>>>> Hi Armin, Maciej >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Thanks for responding. >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> I'm in the process of trying to determine what (if any) of >>>>>>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>>>>> code >>>>>>>>>>>>>>>>>>> I'm >>>>>>>>>>>>>>>>>>> in a >>>>>>>>>>>>>>>>>>> position to share, and I'll get back to you. >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Allowing hinting to the GC would be good. Even better >>>>>>>>>>>>>>>>>>> would be >>>>>>>>>>>>>>>>>>> a >>>>>>>>>>>>>>>>>>> means >>>>>>>>>>>>>>>>>>> to >>>>>>>>>>>>>>>>>>> allow me to (transparently) allocate objects in unmanaged >>>>>>>>>>>>>>>>>>> memory, >>>>>>>>>>>>>>>>>>> but I >>>>>>>>>>>>>>>>>>> would expect that to be a tall order :) >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Thanks, >>>>>>>>>>>>>>>>>>> /Martin >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Hi Martin. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Note that in case you want us to do the work of isolating >>>>>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>>>> problem, >>>>>>>>>>>>>>>>>> we do offer paid support to do that (then we can sign NDAs >>>>>>>>>>>>>>>>>> and >>>>>>>>>>>>>>>>>> stuff). >>>>>>>>>>>>>>>>>> Otherwise we would be more than happy to fix bugs once you >>>>>>>>>>>>>>>>>> isolate >>>>>>>>>>>>>>>>>> a >>>>>>>>>>>>>>>>>> part you can share freely :) >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>> >>>>>>> >>>> >>>> >>> _______________________________________________ pypy-dev mailing list pypy-dev@python.org https://mail.python.org/mailman/listinfo/pypy-dev