11

Since this code work well:

Needs["GeneralUtilities`"]
GeneralUtilities`BenchmarkPlot[{SortBy[#, Identity] &, Sort}, Range, 
 "IncludeFits" -> True, TimeConstraint -> 8]

I want to set "IncludeFits" -> True, TimeConstraint -> 8 in every time to use BenchmarkPlot.So I want to make a private function to meet this need,and I hope Options[myBen] will give all option.

First Try

Options[myBen1] = {"IncludeFits" -> True, TimeConstraint -> 8};
myBen1[x__, opt : OptionsPattern[]] := 
 GeneralUtilities`BenchmarkPlot[x, opt]
myBen1[{SortBy[#, Identity] &, Sort}, Range]

Second Try

SetOptions[myBen2, {"IncludeFits" -> True, TimeConstraint -> 8}];
myBen2 := GeneralUtilities`BenchmarkPlot
myBen2[{SortBy[#, Identity] &, Sort}, Range]

As you see,the two option don't work both in this two tries.What's fault on my code?


PS: Options[GeneralUtilities`BenchmarkPlot] don't include the option of TimeConstraint.But it indeed take effect in fact.

yode
  • 26,686
  • 4
  • 62
  • 167

2 Answers2

13

New analysis (in v10.1)

For your newly stated goal:

If I don't want to build a new function.I just wanna change the GeneralUtilities`BenchmarkPlot's default option into {"IncludeFits" -> True, "Models" -> Automatic, TimeConstraint -> .8}. ... Can it be implemented?

The standard options model in Mathematica means that this should work:

Options[BenchmarkPlot] =
  {TimeConstraint -> 8, MaxIterations -> 1024, 
   "IncludeFits" -> True, "Models" -> Automatic};

It does not however. That means that BenchmarkPlot or one of its subordinate functions is not written correctly. Let's have a look. Using PrintDefinitions from the same package we find that our code will call

GeneralUtilities`Benchmarking`PackagePrivate`plot

Which has the definition (contexts omitted):

plot[data_Association, opts___Rule] := 
  ListLogLogPlot[
   Sequence @@ 
    addfits[data,
     Lookup[{opts}, "Models", Automatic], 
     MemberQ[{opts}, "IncludeFits" -> True]],
   FilterOptions[opts], 
   PlotLegends -> fstyle[Keys[data]], GridLines -> Automatic, 
   PlotMarkers -> {$pmarker}, GridLinesStyle -> Opacity[0.05`], 
   AxesLabel -> {"n", "time (s)"}, ImageSize -> Medium, PlotRangeClipping -> True, 
   Mesh -> False, 
   PlotRange -> {Full, 
     With[{v = Values[data][[All, All, 2]]}, {LogFloor[Min[v]]*1.1`^(-1), 
       LogCeiling[Max[v]]*1.1`}]}];

Please draw your attention to the line MemberQ[{opts}, "IncludeFits" -> True] and note that here opts is the pattern that will match explicit options given to this function and nothing else. BenchmarkPlot does not pass all options to this function either. This means that only explicit appearences of "IncludeFits" will have effect. (Likewise for "Models" from the line above.)

To correct this we either need to expressly pass all of Options[BenchmarkPlot] to this inner plot function, or we need to modify plot so that it considers Options[BenchmarkPlot]. I'll do the latter.

<< "GeneralUtilities`"

With[{plot = GeneralUtilities`Benchmarking`PackagePrivate`plot},
  PrependTo[DownValues[plot],
    HoldPattern[plot[arg___]] :> 
      Block[{$fixGUBPopts = True}, 
        plot[arg, Sequence @@ Options[BenchmarkPlot]]
      ] /; ! TrueQ[$fixGUBPopts]
  ]
];

Options[BenchmarkPlot] =
  {TimeConstraint -> 8, MaxIterations -> 1024,
   "IncludeFits" -> True, "Models" -> Automatic};

BenchmarkPlot[{SortBy[#, Identity] &, Sort}, Range]

enter image description here


Old answer

I wrote a fairly lengthy answer hoping to guide just this sort of thing; please take a look:

From your comment

But Options[myBen4] get {}. I hope it can get all options. Can it be implement?

I think you want something like this.

Options[myBen] = {"IncludeFits" -> True, "Models" -> Automatic, 
   TimeConstraint -> .8};

myBen[args__, opts : OptionsPattern[]] := 
 BenchmarkPlot[args, opts, Sequence @@ Options[myBen]]

myBen[{SortBy[#, Identity] &, Sort}, Range]


(source: clouddn.com)

And it meet the extra need:

Options[myBen]

{"IncludeFits"->True,Models->Automatic,TimeConstraint->0.8}

Glorfindel
  • 547
  • 1
  • 8
  • 14
Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
  • Not very same to you output.Look here. – yode Feb 19 '17 at 07:00
  • @yode That does not make sense. Your output would indicate that the line Options[myBen] = Options[BenchmarkPlot]; failed to work correctly, and I can only see that happening if you failed to load GeneralUtilities first or had an existing definition on myBen. Would you please restart Mathematica and try again? – Mr.Wizard Feb 19 '17 at 07:05
  • 1
    In version 11, TimeConstraint has gone inexplicably missing from Options[BenchmarkPlot]. TimeConstraint is still recognized internally by the implementation. MaxIterations is missing as well, but I don't that option was ever actually implemented, even in V10.1. – WReach Feb 19 '17 at 07:15
  • 1
    I make a edit for fit my case.It's seem I just omit that Sequence @@ Options[myBen].Thanks your answer very very much. :) – yode Feb 19 '17 at 07:20
  • @WReach Thanks for explaining; I was really confused by that! – Mr.Wizard Feb 19 '17 at 07:20
  • If I don't want to build a new function.I just wanna change the GeneralUtilities`BenchmarkPlot's defult option into {"IncludeFits" -> True, "Models" -> Automatic, TimeConstraint -> .8}.And the Options[BenchmarkPlot] also can give all options still.Can it be implemented? – yode Feb 19 '17 at 07:40
  • @yode You mean just Options[BenchmarkPlot] = {TimeConstraint -> 8, MaxIterations -> 1024, "IncludeFits" -> True, "Models" -> Automatic}; ? – Mr.Wizard Feb 19 '17 at 07:45
  • 1
    It's work for you?I have tried it before.Look here. – yode Feb 19 '17 at 07:52
  • @yode Ah, so I see, finally! No, it does not work, but I believe it should. I am working on a different problem but I shall take a look at this in a few minutes. I expect to find a bug or at least an unusual design in BenchmarkPlot. – Mr.Wizard Feb 19 '17 at 07:57
  • @yode The problem is just as I expected. I shall write this up soon. – Mr.Wizard Feb 19 '17 at 08:50
  • @yode Complete. Hopefully my patch still works in version 11. – Mr.Wizard Feb 19 '17 at 09:08
  • It's seem it don't work in "11.0.1 for Microsoft Windows (64-bit) (October 8, 2016)".Look here – yode Feb 19 '17 at 13:58
  • @WReach could you perhaps help? I do not believe I can be of further assistance with the version I am using. – Mr.Wizard Feb 19 '17 at 14:14
  • 2
    In V11.0.1, plot is in a different internal package. The patch needs to be applied to GeneralUtilities`Performance`PackagePrivate`plot. With that change, it works as advertised. – WReach Feb 19 '17 at 15:44
  • 2
    The original patch works up to V10.3.1. The updated patch is needed from V10.4 onward. – WReach Feb 19 '17 at 15:50
4

Including the options in the definition of your auxiliary function seems to work fine:

myBen3[x__, opt : OptionsPattern[]] := 
  GeneralUtilities`BenchmarkPlot[x, opt, "IncludeFits" -> True]

Above I left off the TimeConstraint option from the definition on purpose, because I wanted to showcase the fact that the helper function still correctly passes on extra options to BenchmarkPlot. Compare for instance:

myBen3[{SortBy[#, Identity] &, Sort}, Range, TimeConstraint -> 0.3]
myBen3[{SortBy[#, Identity] &, Sort}, Range]

Mathematica graphics

Mathematica graphics


So a more complete definition would be:

myBen4[x__, opt : OptionsPattern[]] :=
 GeneralUtilities`BenchmarkPlot[x, opt, "IncludeFits" -> True, TimeConstraint -> 8]
MarcoB
  • 67,153
  • 18
  • 91
  • 189
  • But Options[myBen4] get {}.I hope to get all option.Can it be implement? – yode Feb 19 '17 at 05:50
  • If not,I can do it just by myBen := GeneralUtilities`BenchmarkPlot[##, "IncludeFits" -> True, TimeConstraint -> 8] & – yode Feb 19 '17 at 06:01