@@ -401,49 +401,55 @@ def get_changes_table(self, trend_depth=10, force_save=False):
401401 return self ._get_tablecache ()
402402 # Otherwise generate a new changes table
403403 # Get latest revisions for this branch (which also sets the project)
404- lastrevisions = self .get_last_revisions (trend_depth )
404+ lastrevisions = list ( self .get_last_revisions (trend_depth ) )
405405 if not lastrevisions :
406406 return []
407407
408- change_list = []
408+ changerevision = None
409409 pastrevisions = []
410410 if len (lastrevisions ) > 1 :
411411 changerevision = lastrevisions [1 ]
412- change_list = Result .objects .filter (
413- revision = changerevision
414- ).filter (
415- environment = self .environment
416- ).filter (
417- executable = self .executable
418- )
419412 pastrevisions = lastrevisions [trend_depth - 2 :trend_depth + 1 ]
420413
421- result_list = Result .objects .filter (
422- revision = lastrevisions [0 ]
423- ).filter (
424- environment = self .environment
425- ).filter (
426- executable = self .executable
427- )
414+ # Bulk fetch all results needed across current, change, and past revisions
415+ relevant_revs = [lastrevisions [0 ]]
416+ if changerevision :
417+ relevant_revs .append (changerevision )
418+ relevant_revs .extend (pastrevisions )
419+ results_map = {
420+ (r .revision_id , r .benchmark_id ): r
421+ for r in Result .objects .filter (
422+ revision__in = relevant_revs ,
423+ environment = self .environment ,
424+ executable = self .executable ,
425+ )
426+ }
427+
428+ # Fetch and group all benchmarks in one query, preserving DB order
429+ benchmarks_by_units = {}
430+ for bench in Benchmark .objects .all ():
431+ benchmarks_by_units .setdefault (bench .units_title , []).append (bench )
432+
433+ current_rev_id = lastrevisions [0 ].pk
434+ change_rev_id = changerevision .pk if changerevision else None
435+ past_rev_ids = [rev .pk for rev in pastrevisions ]
428436
429437 tablelist = []
430- for units_title in Benchmark .objects .all ().values_list (
431- 'units_title' , flat = True ).distinct ():
438+ for units_title , bench_group in benchmarks_by_units .items ():
432439 currentlist = []
433440 units = ""
434441 hasmin = False
435442 hasmax = False
436443 has_stddev = False
437444 smallest = 1000
438445 totals = {'change' : [], 'trend' : []}
439- for bench in Benchmark . objects . filter ( units_title = units_title ) :
446+ for bench in bench_group :
440447 units = bench .units
441448 lessisbetter = bench .lessisbetter
442- resultquery = result_list .filter (benchmark = bench )
443- if not len (resultquery ):
444- continue
445449
446- resobj = resultquery .filter (benchmark = bench )[0 ]
450+ resobj = results_map .get ((current_rev_id , bench .pk ))
451+ if resobj is None :
452+ continue
447453
448454 std_dev = resobj .std_dev
449455 if std_dev is not None :
@@ -466,13 +472,13 @@ def get_changes_table(self, trend_depth=10, force_save=False):
466472 # Calculate percentage change relative to previous result
467473 result = max (resobj .value , 0 )
468474 change = "-"
469- if len ( change_list ) :
470- c = change_list . filter ( benchmark = bench )
471- if c . count () and result is not None :
472- if c [ 0 ] .value != 0 :
473- change = (result - c [ 0 ] .value ) * 100 / c [ 0 ] .value
474- totals ['change' ].append (result / c [ 0 ] .value )
475- elif c [ 0 ] .value == 0 :
475+ if change_rev_id is not None :
476+ c = results_map . get (( change_rev_id , bench . pk ) )
477+ if c is not None :
478+ if c .value != 0 :
479+ change = (result - c .value ) * 100 / c .value
480+ totals ['change' ].append (result / c .value )
481+ elif c .value == 0 :
476482 if result == 0 :
477483 # 0/0 = 1, in our world
478484 change = 0
@@ -481,27 +487,16 @@ def get_changes_table(self, trend_depth=10, force_save=False):
481487 # n/0 = ∞
482488 change = float ("inf" )
483489 totals ['change' ].append (float ("inf" ))
484- else :
485- # no previous result, no change available
486- pass
487490
488491 # Calculate trend:
489492 # percentage change relative to average of 3 previous results
490- # Calculate past average
491493 result_sum = 0
492494 num_past_results = 0
493- if len (pastrevisions ):
494- for rev in pastrevisions :
495- past_result = Result .objects .filter (
496- revision = rev
497- ).filter (
498- environment = self .environment
499- ).filter (
500- executable = self .executable
501- ).filter (benchmark = bench )
502- if past_result .count ():
503- result_sum += past_result [0 ].value
504- num_past_results += 1
495+ for rev_id in past_rev_ids :
496+ past_r = results_map .get ((rev_id , bench .pk ))
497+ if past_r is not None :
498+ result_sum += past_r .value
499+ num_past_results += 1
505500 trend = "-"
506501 if result_sum :
507502 average = result_sum / num_past_results
0 commit comments