Skip to content

Commit

Permalink
Handle dynamic steps in the evaluator (#200)
Browse files Browse the repository at this point in the history
Signed-off-by: Juan Cruz Viotti <[email protected]>
  • Loading branch information
jviotti authored Nov 21, 2024
1 parent 01b0e1c commit 6ba7628
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 37 deletions.
18 changes: 2 additions & 16 deletions src/evaluator/context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ namespace sourcemeta::blaze {
auto EvaluationContext::push(
const sourcemeta::jsontoolkit::Pointer &relative_schema_location,
const sourcemeta::jsontoolkit::Pointer &relative_instance_location,
const std::size_t &schema_resource, const bool dynamic, const bool track)
-> void {
const bool track) -> void {
// Guard against infinite recursion in a cheap manner, as
// infinite recursion will manifest itself through huge
// ever-growing evaluate paths
Expand All @@ -35,30 +34,17 @@ auto EvaluationContext::push(
// recursion
this->evaluate_path_size += relative_schema_location.size();
}

if (dynamic) {
// Note that we are potentially repeatedly pushing back the
// same schema resource over and over again. However, the
// logic for making sure this list is "pure" takes a lot of
// computation power. Being silly seems faster.
this->resources.push_back(schema_resource);
}
}

auto EvaluationContext::pop(const std::size_t relative_schema_location_size,
const std::size_t relative_instance_location_size,
const bool dynamic, const bool track) -> void {
const bool track) -> void {
if (track) {
this->evaluate_path.pop_back(relative_schema_location_size);
this->instance_location.pop_back(relative_instance_location_size);
} else {
this->evaluate_path_size -= relative_schema_location_size;
}

if (dynamic) {
assert(!this->resources.empty());
this->resources.pop_back();
}
}

auto EvaluationContext::hash(
Expand Down
48 changes: 30 additions & 18 deletions src/evaluator/evaluator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -70,16 +70,20 @@ auto evaluate_step(
const auto &step_category{std::get<step_type>(step)}; \
const auto track{step_category.track || callback.has_value()}; \
context.push(step_category.relative_schema_location, \
step_category.relative_instance_location, \
step_category.schema_resource, step_category.dynamic, track); \
step_category.relative_instance_location, track); \
if (step_category.dynamic) { \
context.resources.push_back(step_category.schema_resource); \
} \
const auto &target{resolve_target( \
property_target, \
sourcemeta::jsontoolkit::get( \
instance, step_category.relative_instance_location))}; \
if (!(precondition)) { \
context.pop(step_category.relative_schema_location.size(), \
step_category.relative_instance_location.size(), \
step_category.dynamic, track); \
step_category.relative_instance_location.size(), track); \
if (step_category.dynamic) { \
context.resources.pop_back(); \
} \
SOURCEMETA_TRACE_END(trace_id, STRINGIFY(step_type)); \
return true; \
} \
Expand All @@ -94,14 +98,18 @@ auto evaluate_step(
const auto &step_category{std::get<step_type>(step)}; \
const auto track{step_category.track || callback.has_value()}; \
context.push(step_category.relative_schema_location, \
step_category.relative_instance_location, \
step_category.schema_resource, step_category.dynamic, track); \
step_category.relative_instance_location, track); \
if (step_category.dynamic) { \
context.resources.push_back(step_category.schema_resource); \
} \
const auto &maybe_target{resolve_string_target( \
property_target, instance, step_category.relative_instance_location)}; \
if (!maybe_target.has_value()) { \
context.pop(step_category.relative_schema_location.size(), \
step_category.relative_instance_location.size(), \
step_category.dynamic, track); \
step_category.relative_instance_location.size(), track); \
if (step_category.dynamic) { \
context.resources.pop_back(); \
} \
SOURCEMETA_TRACE_END(trace_id, STRINGIFY(step_type)); \
return true; \
} \
Expand Down Expand Up @@ -132,8 +140,10 @@ auto evaluate_step(
} \
const auto track{step_category.track || callback.has_value()}; \
context.push(step_category.relative_schema_location, \
step_category.relative_instance_location, \
step_category.schema_resource, step_category.dynamic, track); \
step_category.relative_instance_location, track); \
if (step_category.dynamic) { \
context.resources.push_back(step_category.schema_resource); \
} \
assert(!step_category.relative_instance_location.empty()); \
if (callback.has_value()) { \
callback.value()(EvaluationType::Pre, true, step, context.evaluate_path, \
Expand All @@ -146,8 +156,10 @@ auto evaluate_step(
const auto &step_category{std::get<step_type>(step)}; \
const auto track{step_category.track || callback.has_value()}; \
context.push(step_category.relative_schema_location, \
step_category.relative_instance_location, \
step_category.schema_resource, step_category.dynamic, track); \
step_category.relative_instance_location, track); \
if (step_category.dynamic) { \
context.resources.push_back(step_category.schema_resource); \
} \
if (callback.has_value()) { \
callback.value()(EvaluationType::Pre, true, step, context.evaluate_path, \
context.instance_location, context.null); \
Expand Down Expand Up @@ -175,8 +187,10 @@ auto evaluate_step(
context.null); \
} \
context.pop(step_category.relative_schema_location.size(), \
step_category.relative_instance_location.size(), \
step_category.dynamic, track); \
step_category.relative_instance_location.size(), track); \
if (step_category.dynamic) { \
context.resources.pop_back(); \
} \
SOURCEMETA_TRACE_END(trace_id, STRINGIFY(step_type)); \
return result;

Expand All @@ -200,17 +214,15 @@ auto evaluate_step(
const auto track{step_category.track || callback.has_value()}; \
assert(track); \
context.push(step_category.relative_schema_location, \
step_category.relative_instance_location, \
step_category.schema_resource, step_category.dynamic, track); \
step_category.relative_instance_location, track); \
if (callback.has_value()) { \
callback.value()(EvaluationType::Pre, true, step, context.evaluate_path, \
destination, context.null); \
callback.value()(EvaluationType::Post, true, step, context.evaluate_path, \
destination, annotation_value); \
} \
context.pop(step_category.relative_schema_location.size(), \
step_category.relative_instance_location.size(), \
step_category.dynamic, track); \
step_category.relative_instance_location.size(), track); \
SOURCEMETA_TRACE_END(trace_id, STRINGIFY(step_type)); \
return true;

Expand Down
5 changes: 2 additions & 3 deletions src/evaluator/include/sourcemeta/blaze/evaluator_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,10 @@ class SOURCEMETA_BLAZE_EVALUATOR_EXPORT EvaluationContext {

auto push(const sourcemeta::jsontoolkit::Pointer &relative_schema_location,
const sourcemeta::jsontoolkit::Pointer &relative_instance_location,
const std::size_t &schema_resource, const bool dynamic,
const bool track) -> void;
auto pop(const std::size_t relative_schema_location_size,
const std::size_t relative_instance_location_size,
const bool dynamic, const bool track) -> void;
const std::size_t relative_instance_location_size, const bool track)
-> void;

///////////////////////////////////////////////
// References and anchors
Expand Down

5 comments on commit 6ba7628

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark (macos/llvm)

Benchmark suite Current: 6ba7628 Previous: 01b0e1c Ratio
Compiler_Draft6_AdaptiveCard 32874253374.999966 ns/iter 35087999957.999954 ns/iter 0.94
Compiler_2019_09_OMC_JSON_V2 7445065750.000026 ns/iter 7364888458.999986 ns/iter 1.01
Evaluator_Draft4_Meta_1_No_Callback 316.1394086427567 ns/iter 296.1244358352388 ns/iter 1.07
Evaluator_Draft4_Required_Properties 450.6620471897142 ns/iter 451.16744421819027 ns/iter 1.00
Evaluator_Draft4_Many_Optional_Properties_Minimal_Match 29.346204515617565 ns/iter 47.80612294599352 ns/iter 0.61
Evaluator_Draft4_Few_Optional_Properties_Minimal_Match 16.286284268984875 ns/iter 16.61379295712934 ns/iter 0.98
Evaluator_Draft4_Items_Schema 846.5621298025235 ns/iter 846.7285776901231 ns/iter 1.00
Evaluator_Draft4_Nested_Object 4.398489997672311 ns/iter 4.378634229480897 ns/iter 1.00
Evaluator_Draft4_Properties_Triad_Optional 1104.7126506431478 ns/iter 1226.2785436713689 ns/iter 0.90
Evaluator_Draft4_Properties_Triad_Closed 792.4494203241684 ns/iter 866.149028629775 ns/iter 0.91
Evaluator_Draft4_Properties_Triad_Required 1091.4448500181416 ns/iter 1094.2018319027748 ns/iter 1.00
Evaluator_Draft4_Properties_Closed 121.82840435849756 ns/iter 203.66677475000924 ns/iter 0.60
Evaluator_Draft4_Non_Recursive_Ref 16.29041964869751 ns/iter 16.292672645441897 ns/iter 1.00
Evaluator_Draft4_Pattern_Properties_True 1227.6176474215551 ns/iter 1262.2574522553184 ns/iter 0.97
Evaluator_Draft4_Ref_To_Single_Property 17.926868357641332 ns/iter 17.487818255449014 ns/iter 1.03
Evaluator_Draft4_Additional_Properties_Type 27.402445994060905 ns/iter 28.295128054264598 ns/iter 0.97
Evaluator_Draft4_Nested_Oneof 105.15139021138607 ns/iter 101.58861325151202 ns/iter 1.04
Evaluator_Draft4_Long_Enum 24.683145991176023 ns/iter 25.372809010334787 ns/iter 0.97
Evaluator_Draft4_Type_Object 10.400092870201158 ns/iter 10.432657396444796 ns/iter 1.00
Evaluator_Draft6_Property_Names 331.0307148358441 ns/iter 344.18004495004277 ns/iter 0.96
Evaluator_Draft7_If_Then_Else 44.84361965934845 ns/iter 45.24852014257997 ns/iter 0.99
Evaluator_Draft7_Vercel_1 98866.23491837735 ns/iter 99551.52203976469 ns/iter 0.99
Evaluator_2019_09_Unevaluated_Properties 234.43542275415837 ns/iter 239.77455704136364 ns/iter 0.98
Evaluator_2019_09_OMC_JSON_V2_1 6773.275414380326 ns/iter 7138.695379147711 ns/iter 0.95
Evaluator_2020_12_Dynamic_Ref 712.5673270192636 ns/iter 744.1682319213471 ns/iter 0.96

This comment was automatically generated by workflow using github-action-benchmark.

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark (linux/llvm)

Benchmark suite Current: 6ba7628 Previous: 01b0e1c Ratio
Compiler_Draft6_AdaptiveCard 57933851975.99997 ns/iter 57902491956.00001 ns/iter 1.00
Compiler_2019_09_OMC_JSON_V2 10993956199.000025 ns/iter 11007720694 ns/iter 1.00
Evaluator_Draft4_Meta_1_No_Callback 478.72336305802963 ns/iter 485.8900804417328 ns/iter 0.99
Evaluator_Draft4_Required_Properties 957.7069340217801 ns/iter 956.9830314447219 ns/iter 1.00
Evaluator_Draft4_Many_Optional_Properties_Minimal_Match 58.33495333838399 ns/iter 58.69705252758853 ns/iter 0.99
Evaluator_Draft4_Few_Optional_Properties_Minimal_Match 39.28950076407092 ns/iter 38.85853045506177 ns/iter 1.01
Evaluator_Draft4_Items_Schema 1501.3066449057028 ns/iter 1519.4547887699023 ns/iter 0.99
Evaluator_Draft4_Nested_Object 12.09205275682082 ns/iter 12.305833660015493 ns/iter 0.98
Evaluator_Draft4_Properties_Triad_Optional 1309.1830674469916 ns/iter 1325.0447365987034 ns/iter 0.99
Evaluator_Draft4_Properties_Triad_Closed 1024.0597257346692 ns/iter 1030.230764006626 ns/iter 0.99
Evaluator_Draft4_Properties_Triad_Required 1357.2495267278734 ns/iter 1369.847654020241 ns/iter 0.99
Evaluator_Draft4_Properties_Closed 172.84447143631616 ns/iter 170.37340233390216 ns/iter 1.01
Evaluator_Draft4_Non_Recursive_Ref 47.3755330993062 ns/iter 47.38491713397765 ns/iter 1.00
Evaluator_Draft4_Pattern_Properties_True 1977.3750106161124 ns/iter 2061.9241182706046 ns/iter 0.96
Evaluator_Draft4_Ref_To_Single_Property 39.725934085974785 ns/iter 38.416839763054966 ns/iter 1.03
Evaluator_Draft4_Additional_Properties_Type 76.47396712204572 ns/iter 76.65638077313281 ns/iter 1.00
Evaluator_Draft4_Nested_Oneof 191.61618376326635 ns/iter 190.2045175072331 ns/iter 1.01
Evaluator_Draft4_Long_Enum 34.7875848922764 ns/iter 35.11093926277793 ns/iter 0.99
Evaluator_Draft4_Type_Object 24.13156642440499 ns/iter 24.543594672723792 ns/iter 0.98
Evaluator_Draft6_Property_Names 649.8082558529774 ns/iter 624.6762008583129 ns/iter 1.04
Evaluator_Draft7_If_Then_Else 89.44994357483324 ns/iter 89.56655036345732 ns/iter 1.00
Evaluator_Draft7_Vercel_1 141986.1800239179 ns/iter 150160.56724067335 ns/iter 0.95
Evaluator_2019_09_Unevaluated_Properties 279.5282933130534 ns/iter 285.70069478104836 ns/iter 0.98
Evaluator_2019_09_OMC_JSON_V2_1 10436.90279111681 ns/iter 10472.246625676395 ns/iter 1.00
Evaluator_2020_12_Dynamic_Ref 1131.8964518490318 ns/iter 1075.8061865317113 ns/iter 1.05

This comment was automatically generated by workflow using github-action-benchmark.

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark (linux/gcc)

Benchmark suite Current: 6ba7628 Previous: 01b0e1c Ratio
Evaluator_2020_12_Dynamic_Ref 1077.5724619727575 ns/iter 1084.148469028361 ns/iter 0.99
Evaluator_2019_09_Unevaluated_Properties 337.7914690348356 ns/iter 349.9776965208393 ns/iter 0.97
Evaluator_2019_09_OMC_JSON_V2_1 12824.18571905082 ns/iter 13016.488932253244 ns/iter 0.99
Evaluator_Draft7_If_Then_Else 79.80617312882747 ns/iter 80.38128407644824 ns/iter 0.99
Evaluator_Draft7_Vercel_1 149051.41849662238 ns/iter 161636.7065217256 ns/iter 0.92
Evaluator_Draft6_Property_Names 1256.1841736682943 ns/iter 1320.169730344837 ns/iter 0.95
Evaluator_Draft4_Meta_1_No_Callback 544.99518359693 ns/iter 586.6146567888844 ns/iter 0.93
Evaluator_Draft4_Required_Properties 1864.9251306247927 ns/iter 1974.6285506898405 ns/iter 0.94
Evaluator_Draft4_Many_Optional_Properties_Minimal_Match 52.71227745717979 ns/iter 52.907227049779245 ns/iter 1.00
Evaluator_Draft4_Few_Optional_Properties_Minimal_Match 41.54889875985314 ns/iter 43.49640800730207 ns/iter 0.96
Evaluator_Draft4_Items_Schema 1336.364236164436 ns/iter 1338.85534250799 ns/iter 1.00
Evaluator_Draft4_Nested_Object 8.177937381646633 ns/iter 6.820188739599651 ns/iter 1.20
Evaluator_Draft4_Properties_Triad_Optional 1361.7414123384053 ns/iter 1398.3039726191378 ns/iter 0.97
Evaluator_Draft4_Properties_Triad_Closed 1066.9785102862131 ns/iter 1111.522762015356 ns/iter 0.96
Evaluator_Draft4_Properties_Triad_Required 1434.7913154158143 ns/iter 1468.6204527497794 ns/iter 0.98
Evaluator_Draft4_Properties_Closed 212.71472332369993 ns/iter 219.805344188962 ns/iter 0.97
Evaluator_Draft4_Non_Recursive_Ref 59.011878098750415 ns/iter 59.00494842698748 ns/iter 1.00
Evaluator_Draft4_Pattern_Properties_True 2095.041575388007 ns/iter 2222.7752493391945 ns/iter 0.94
Evaluator_Draft4_Ref_To_Single_Property 45.97740634419776 ns/iter 47.93170450237031 ns/iter 0.96
Evaluator_Draft4_Additional_Properties_Type 113.62693423086438 ns/iter 113.5416877605631 ns/iter 1.00
Evaluator_Draft4_Nested_Oneof 156.7140709518004 ns/iter 168.89045493634853 ns/iter 0.93
Evaluator_Draft4_Long_Enum 26.990644426976097 ns/iter 26.982814005936074 ns/iter 1.00
Evaluator_Draft4_Type_Object 18.68449182122194 ns/iter 19.591935664594114 ns/iter 0.95
Compiler_2019_09_OMC_JSON_V2 11400943141.000084 ns/iter 11373929497.999939 ns/iter 1.00
Compiler_Draft6_AdaptiveCard 66186420902.00001 ns/iter 65197155854.000015 ns/iter 1.02

This comment was automatically generated by workflow using github-action-benchmark.

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark (macos/gcc)

Benchmark suite Current: 6ba7628 Previous: 01b0e1c Ratio
Compiler_Draft6_AdaptiveCard 45999326944.3512 ns/iter 48723938941.95557 ns/iter 0.94
Compiler_2019_09_OMC_JSON_V2 8437051057.815552 ns/iter 9046262025.83313 ns/iter 0.93
Evaluator_Draft4_Meta_1_No_Callback 310.39710450552474 ns/iter 321.3179259295507 ns/iter 0.97
Evaluator_Draft4_Required_Properties 529.1378941506025 ns/iter 542.882813282086 ns/iter 0.97
Evaluator_Draft4_Many_Optional_Properties_Minimal_Match 32.575315646709804 ns/iter 34.275650355771525 ns/iter 0.95
Evaluator_Draft4_Few_Optional_Properties_Minimal_Match 19.420506930437327 ns/iter 19.662920103242392 ns/iter 0.99
Evaluator_Draft4_Items_Schema 932.7842495410666 ns/iter 975.4220197948879 ns/iter 0.96
Evaluator_Draft4_Nested_Object 4.1703415731794795 ns/iter 4.172624492064155 ns/iter 1.00
Evaluator_Draft4_Properties_Triad_Optional 1114.4984831819413 ns/iter 1122.5498494975775 ns/iter 0.99
Evaluator_Draft4_Properties_Triad_Closed 891.3909887756215 ns/iter 902.5222248831755 ns/iter 0.99
Evaluator_Draft4_Properties_Triad_Required 1105.2265452650315 ns/iter 1167.6079714575817 ns/iter 0.95
Evaluator_Draft4_Properties_Closed 124.20954752349449 ns/iter 140.20024409479078 ns/iter 0.89
Evaluator_Draft4_Non_Recursive_Ref 25.530977471349644 ns/iter 29.132127684307324 ns/iter 0.88
Evaluator_Draft4_Pattern_Properties_True 1699.562062296388 ns/iter 1703.8387722850462 ns/iter 1.00
Evaluator_Draft4_Ref_To_Single_Property 18.565421623550186 ns/iter 18.49553273750065 ns/iter 1.00
Evaluator_Draft4_Additional_Properties_Type 40.92814758197576 ns/iter 42.73189509381196 ns/iter 0.96
Evaluator_Draft4_Nested_Oneof 112.84177435943627 ns/iter 125.58628558162319 ns/iter 0.90
Evaluator_Draft4_Long_Enum 17.695104771587694 ns/iter 18.261653299949412 ns/iter 0.97
Evaluator_Draft4_Type_Object 12.404142579231737 ns/iter 12.924768504848778 ns/iter 0.96
Evaluator_Draft6_Property_Names 443.48401770068085 ns/iter 447.4183978610088 ns/iter 0.99
Evaluator_Draft7_If_Then_Else 50.136399269104004 ns/iter 51.77199023425334 ns/iter 0.97
Evaluator_Draft7_Vercel_1 103391.80970252064 ns/iter 114176.82197090218 ns/iter 0.91
Evaluator_2019_09_Unevaluated_Properties 253.68247344459735 ns/iter 283.0707227343961 ns/iter 0.90
Evaluator_2019_09_OMC_JSON_V2_1 6842.760967584698 ns/iter 7403.441109473292 ns/iter 0.92
Evaluator_2020_12_Dynamic_Ref 857.3820668328074 ns/iter 885.7528493808336 ns/iter 0.97

This comment was automatically generated by workflow using github-action-benchmark.

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark (windows/msvc)

Benchmark suite Current: 6ba7628 Previous: 01b0e1c Ratio
Compiler_Draft6_AdaptiveCard 120826007699.99998 ns/iter 118165276700.00005 ns/iter 1.02
Compiler_2019_09_OMC_JSON_V2 25532280399.999992 ns/iter 25309185000.00007 ns/iter 1.01
Evaluator_Draft4_Meta_1_No_Callback 899.0429468558253 ns/iter 873.7793526784848 ns/iter 1.03
Evaluator_Draft4_Required_Properties 1346.0219214189892 ns/iter 1359.15890216138 ns/iter 0.99
Evaluator_Draft4_Many_Optional_Properties_Minimal_Match 146.90506696426147 ns/iter 148.87412946425877 ns/iter 0.99
Evaluator_Draft4_Few_Optional_Properties_Minimal_Match 96.79843764290874 ns/iter 94.18291990254993 ns/iter 1.03
Evaluator_Draft4_Items_Schema 2721.4215975792386 ns/iter 2700.582858052826 ns/iter 1.01
Evaluator_Draft4_Nested_Object 54.442383928566024 ns/iter 55.8033928571433 ns/iter 0.98
Evaluator_Draft4_Properties_Triad_Optional 4816.434166458041 ns/iter 4817.072158100167 ns/iter 1.00
Evaluator_Draft4_Properties_Triad_Closed 3878.147321428723 ns/iter 3867.4034510651904 ns/iter 1.00
Evaluator_Draft4_Properties_Triad_Required 4783.09322151148 ns/iter 4875.053000000662 ns/iter 0.98
Evaluator_Draft4_Properties_Closed 360.85856744905055 ns/iter 359.72104284465627 ns/iter 1.00
Evaluator_Draft4_Non_Recursive_Ref 150.13650669034217 ns/iter 145.74418545784638 ns/iter 1.03
Evaluator_Draft4_Pattern_Properties_True 7767.006696427968 ns/iter 7808.330357142218 ns/iter 0.99
Evaluator_Draft4_Ref_To_Single_Property 101.06735937501553 ns/iter 94.72218750001814 ns/iter 1.07
Evaluator_Draft4_Additional_Properties_Type 235.2376411565392 ns/iter 223.379656249989 ns/iter 1.05
Evaluator_Draft4_Nested_Oneof 379.6849679133975 ns/iter 359.2358352337847 ns/iter 1.06
Evaluator_Draft4_Long_Enum 122.84446428570358 ns/iter 117.33951562501233 ns/iter 1.05
Evaluator_Draft4_Type_Object 87.48571484438837 ns/iter 86.43973274821839 ns/iter 1.01
Evaluator_Draft6_Property_Names 1157.56906250013 ns/iter 1150.6292857144933 ns/iter 1.01
Evaluator_Draft7_If_Then_Else 187.57951674815314 ns/iter 190.1719991225202 ns/iter 0.99
Evaluator_Draft7_Vercel_1 244447.40542355165 ns/iter 234126.91663872314 ns/iter 1.04
Evaluator_2019_09_Unevaluated_Properties 710.754196428606 ns/iter 702.5023437500064 ns/iter 1.01
Evaluator_2019_09_OMC_JSON_V2_1 15533.627232139834 ns/iter 15735.850446430633 ns/iter 0.99
Evaluator_2020_12_Dynamic_Ref 2205.183125000332 ns/iter 2123.984687499814 ns/iter 1.04

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.