@@ -425,20 +425,22 @@ function get_testset_string(remove_last=false)
425
425
end
426
426
427
427
# non-inline testset with regex filtering support
428
- macro testset (mod:: String , isfinal:: Bool , rx:: Regex , desc:: String , options, chan, body)
429
- Testset. testset_beginend (mod, isfinal, rx, desc, options, chan, body, __source__)
428
+ macro testset (mod:: String , isfinal:: Bool , rx:: Regex , desc:: String , options,
429
+ stats:: Bool , chan, body)
430
+ Testset. testset_beginend (mod, isfinal, rx, desc, options, stats, chan, body, __source__)
430
431
end
431
432
432
- macro testset (mod:: String , isfinal:: Bool , rx:: Regex , desc:: Union{String,Expr} , options, chan,
433
- loopiter, loopvals, body)
434
- Testset. testset_forloop (mod, isfinal, rx, desc, options, chan, loopiter, loopvals, body, __source__)
433
+ macro testset (mod:: String , isfinal:: Bool , rx:: Regex , desc:: Union{String,Expr} , options,
434
+ stats:: Bool , chan, loopiter, loopvals, body)
435
+ Testset. testset_forloop (mod, isfinal, rx, desc, options,
436
+ stats, chan, loopiter, loopvals, body, __source__)
435
437
end
436
438
437
439
"""
438
440
Generate the code for a `@testset` with a `begin`/`end` argument
439
441
"""
440
442
function testset_beginend (mod:: String , isfinal:: Bool , rx:: Regex , desc:: String , options,
441
- chan, tests, source)
443
+ stats :: Bool , chan, tests, source)
442
444
# Generate a block of code that initializes a new testset, adds
443
445
# it to the task local storage, evaluates the test(s), before
444
446
# finally removing the testset and giving it a chance to take
@@ -460,19 +462,12 @@ function testset_beginend(mod::String, isfinal::Bool, rx::Regex, desc::String, o
460
462
# by wrapping the body in a function
461
463
local RNG = default_rng ()
462
464
local oldrng = copy (RNG)
463
- local timed
464
- local rss
465
- local compile_time
466
465
try
467
466
# RNG is re-seeded with its own seed to ease reproduce a failed test
468
467
Random. seed! (RNG. seed)
469
- rss = Sys. maxrss ()
470
- compile_time = cumulative_compile_time_ns ()
471
468
let
472
- timed = @timed $ (esc (tests))
469
+ ts . timed = @stats $ stats $ (esc (tests))
473
470
end
474
- rss = Sys. maxrss () - rss
475
- compile_time = cumulative_compile_time_ns () - compile_time
476
471
catch err
477
472
err isa InterruptException && rethrow ()
478
473
# something in the test block threw an error. Count that as an
@@ -482,8 +477,6 @@ function testset_beginend(mod::String, isfinal::Bool, rx::Regex, desc::String, o
482
477
finally
483
478
copy! (RNG, oldrng)
484
479
pop_testset ()
485
- @isdefined (timed) &&
486
- set_timed! (ts, timed, rss, compile_time)
487
480
ret = finish (ts, $ chan)
488
481
end
489
482
ret
501
494
"""
502
495
Generate the code for a `@testset` with a `for` loop argument
503
496
"""
504
- function testset_forloop (mod:: String , isfinal:: Bool , rx:: Regex , desc:: Union{String,Expr} , options, chan,
505
- loopiter, loopvals,
506
- tests, source)
497
+ function testset_forloop (mod:: String , isfinal:: Bool , rx:: Regex , desc:: Union{String,Expr} ,
498
+ options, stats, chan, loopiter, loopvals, tests, source)
507
499
508
500
# Pull out the loop variables. We might need them for generating the
509
501
# description and we'll definitely need them for generating the
@@ -519,8 +511,6 @@ function testset_forloop(mod::String, isfinal::Bool, rx::Regex, desc::Union{Stri
519
511
# they can be handled properly by `finally` lowering.
520
512
if ! first_iteration
521
513
pop_testset ()
522
- timed != = nothing &&
523
- set_timed! (ts, timed, rss, compile_time)
524
514
push! (arr, finish (ts, $ chan))
525
515
# it's 1000 times faster to copy from tmprng rather than calling Random.seed!
526
516
copy! (RNG, tmprng)
@@ -532,14 +522,9 @@ function testset_forloop(mod::String, isfinal::Bool, rx::Regex, desc::Union{Stri
532
522
push_testset (ts)
533
523
first_iteration = false
534
524
try
535
- rss = Sys. maxrss ()
536
- compile_time = cumulative_compile_time_ns ()
537
- timed = nothing
538
525
let
539
- timed = @timed $ (esc (tests))
526
+ ts . timed = @stats $ stats $ (esc (tests))
540
527
end
541
- rss = Sys. maxrss () - rss
542
- compile_time = cumulative_compile_time_ns () - compile_time
543
528
catch err
544
529
err isa InterruptException && rethrow ()
545
530
# Something in the test block threw an error. Count that as an
@@ -556,9 +541,6 @@ function testset_forloop(mod::String, isfinal::Bool, rx::Regex, desc::Union{Stri
556
541
local oldrng = copy (RNG)
557
542
Random. seed! (RNG. seed)
558
543
local tmprng = copy (RNG)
559
- local timed
560
- local rss
561
- local compile_time
562
544
try
563
545
let
564
546
$ (Expr (:for , Expr (:block , [esc (v) for v in loopvars]. .. ), blk))
@@ -567,8 +549,6 @@ function testset_forloop(mod::String, isfinal::Bool, rx::Regex, desc::Union{Stri
567
549
# Handle `return` in test body
568
550
if ! first_iteration
569
551
pop_testset ()
570
- timed != = nothing &&
571
- set_timed! (ts, timed, rss, compile_time)
572
552
push! (arr, finish (ts, $ chan))
573
553
end
574
554
copy! (RNG, oldrng)
@@ -577,16 +557,6 @@ function testset_forloop(mod::String, isfinal::Bool, rx::Regex, desc::Union{Stri
577
557
end
578
558
end
579
559
580
- function set_timed! (ts, timed, rss, compile_time)
581
- # on Julia < 1.5, @timed returns a Tuple; here we give the names as in
582
- # Julia 1.5+, but we filter out the `val` field, unused here
583
- ts. timed = (time = timed[2 ], bytes = timed[3 ], gctime = timed[4 ],
584
- rss = rss, compile_time = compile_time)
585
- # julia/test/runtests.jl uses timed.gcstats.total_time/10^9, which is equal to gctime
586
- # (timed[5] == timed.gcstats)
587
- ts
588
- end
589
-
590
560
function set_timed! (ts)
591
561
if ts. overall
592
562
foreach (get_timed!, ts. results)
600
570
601
571
get_timed! (ts) = isempty (ts. timed) ? set_timed! (ts) : ts
602
572
573
+ # adapted from @timed in Julia/base/timing.jl
574
+ # also, @timed inserts a `while false; end` compiler heuristic, which destroys perfs here
575
+ macro stats (yes, ex)
576
+ quote
577
+ if $ yes
578
+ local stats = Base. gc_num ()
579
+ local elapsedtime = time_ns ()
580
+ local rss = Sys. maxrss ()
581
+ local compile_time = cumulative_compile_time_ns ()
582
+ end
583
+ local val = $ (esc (ex))
584
+ if $ yes
585
+ elapsedtime = time_ns () - elapsedtime
586
+ local diff = Base. GC_Diff (Base. gc_num (), stats)
587
+ rss = Sys. maxrss () - rss
588
+ compile_time = cumulative_compile_time_ns () - compile_time
589
+ (time= elapsedtime/ 1e9 , bytes= diff. allocd, gctime= diff. total_time/ 1e9 ,
590
+ rss = rss, compile_time = compile_time)
591
+ else
592
+ NamedTuple ()
593
+ end
594
+ end
595
+ end
596
+
603
597
cumulative_compile_time_ns () =
604
598
isdefined (Base, :cumulative_compile_time_ns ) ?
605
599
Base. cumulative_compile_time_ns () :
0 commit comments