Marking as postponed until bug #45367 is solved.

I added a dependency on bug #45367 with is a report on adding PartialMatching to inputParser.

I benchmarked with the following code:
N = 400;
bm = zeros (N,1);
for i = 1:N;
tic;
x = odeset ("RelTol", 1e1);
#x = odeset ("FooBar", 1e1);
bm(i) = toc;
endfor
And then median(bm) to not have a few outliers change the result.
Results:
Old code: 0.0026391
New code: 0.0026280
Basically the same. I don't trust that my computer is accurately timing events down to microsecond precision anyways. I left the code as is.

oops, you are right, sorry!
Does the new attached patch look correct to you?
With this I see a suspiciously substantial speedup ...
without patch
>> tic, test odeset, toc
PASSES 9 out of 9 tests
Elapsed time is 0.443603 seconds.
with patch
>> tic, test odeset, toc
PASSES 9 out of 9 tests
Elapsed time is 0.124976 seconds.
(file #38801)

Your patch has
+ if (! isempty (p.Unmatched))
+ ## Merge extra fields into existing odestruct
+ odestruct_extra = p.Unmatched;
+ xtra_fields = fieldnames (odestruct_extra);
but p.Unmatched is a scalar struct of size 1x1 (by definition, not empty) so this branch of the code will always be taken. That's why I changed it to depend on fieldnames to make sure the struct was actually empty.

Rik,
I was aware of the behaviour of isempty on structs
but in my patch I was testing
isempty (p.Unmatched)
as p.Unmatched is set to an empty struct before p.parse ()
it should be empty if and only if no unmatched parameters are found.

True, and so to be completely general one would have to code
numel (x) == 0  isempty (fieldnames (x))
However, for this case there is no need since the structure is directly returned from inputParser and hasn't had the deletions necessary to trigger the issue in question.

> However, if you use fieldnames then both "empty" structures above report that they are empty.
This alone will not work if the struct had fields before and was then "emptied" (depending on how define empty struct).
octave:1> x.foo = 1;
octave:2> x(1) = []
x =
1x0 struct array containing the fields:
foo
octave:3> fieldnames (x)
ans =
{
[1,1] = foo
}

@Carlo: I tried "isempty (odestruct_extra)" the first time I recoded the routine, but discovered a quirk. isempty() returns true if the number of elements is 0. Thus a scalar structure is a 1x1 object and has one element, even if it has no field names. This is not what most people mean when they say "the structure is empty". See the following code in Octave which is unintuitive.
octave:1> x = struct ()
x =
scalar structure containing the fields:
octave:2> size (x)
ans =
1 1
octave:3> isempty (x)
ans = 0
octave:4> y = struct ([])
y =
0x0 struct array containing the fields:
octave:5> size (y)
ans =
0 0
octave:6> isempty (y)
ans = 1
However, if you use fieldnames then both "empty" structures above report that they are empty. Searching around on the Internet I found that the fieldnames method is, indeed, the recommended way to test structures for being empty.

Rik,
I observed the following:
>> tic, isempty (odestruct_extra); iet = toc
iet = 3.3140e05
>> tic, xtra_fields = fieldnames (odestruct_extra); ! (isempty (xtra_fields)); ieft = toc
ieft = 1.9383e04
>> tic, a = odeset (); ost = toc
ost = 0.0055351
So the attached change may improve performance by a few more hundreds of microseconds.
c.
(file #38770)

I made a change so that Octave emits a warning when an unknown property is used (http://hg.savannah.gnu.org/hgweb/octave/rev/c28648e039da).
Changing report status back to confirmed and release to dev. The final fix should take place on the development branch.

From email, workaround #1 depends on support for nonexact matching in inputParser class. Temporary fix should be workaround #2, to issue a warning.
I added notes to odeset.m to document this (http://hg.savannah.gnu.org/hgweb/octave/rev/0b21aece4b93).

Possible workarounds include:
1) Implementing nonexact match in Octave
2) Generating a warning when a property name does not match a known value

In Matlab, odeset will match a partial property name to the exact property name. Octave does not do this. Instead, it creates a new property under the abbreviated name.
This is a problem. Code on Matlab which makes use of this feature does not generate any warning, therefore, there is no indication that the option should be written more specifically. When this code is ported to Octave, it will run, but differentent results will be obtained because some options have not been set identically. As an example,
odeset ('Rel', 1e12)
will set RelTol to a very strict 1e12 in Matlab, but leave it at the default value in Octave.
Test code:
% Should ignore case and set RelTol, is list of properties still alphabetic?
x = odeset ('reltol', 1e1)
% Does Matlab error or warn when option value is incorrect?
y = odeset ('RelTal', 1e2)
% Does Matlab autocomplete to nearest available property as for graphics?
z = odeset ('Rel', 1e3)
% Can arbitrary properties be added?
w = odeset ('MyCustomProperty', 1)
Results:
These are the outputs on r2016a:
x = odeset ('reltol', 1e1)
x =
AbsTol: []
BDF: []
Events: []
InitialStep: []
Jacobian: []
JConstant: []
JPattern: []
Mass: []
MassSingular: []
MaxOrder: []
MaxStep: []
NonNegative: []
NormControl: []
OutputFcn: []
OutputSel: []
Refine: []
RelTol: 0.1000
Stats: []
Vectorized: []
MStateDependence: []
MvPattern: []
InitialSlope: []
___________________
y = odeset ('RelTal', 1e2)
Error using odeset (line 225)
Unrecognized property name 'RelTal'.
__________________
z = odeset ('Rel', 1e3)
z =
AbsTol: []
BDF: []
Events: []
InitialStep: []
Jacobian: []
JConstant: []
JPattern: []
Mass: []
MassSingular: []
MaxOrder: []
MaxStep: []
NonNegative: []
NormControl: []
OutputFcn: []
OutputSel: []
Refine: []
RelTol: 1.0000e03
Stats: []
Vectorized: []
MStateDependence: []
MvPattern: []
InitialSlope: []
_______________________
w = odeset ('MyCustomProperty', 1)
Error using odeset (line 225)
Unrecognized property name 'MyCustomProperty'.
