MATLAB: Eval seems to be faster than other alternatives in this example?!

anti-patternevalinefficientMATLABslowstructurestimeit

Hi
I know that using eval is highly discouraged, but for the below test case it seems to be faster than other options. Can you help me explain this and let me know which alternative you prefer?
struct1.data = 2*ones(1e3);
struct2.data = 4*ones(1e3);
struct(1).data = 2*ones(1e3);
struct(2).data = 4*ones(1e3);
selected_struct_str = 'struct1';
selected_struct_num = 1;
num_iter = 10;
tic
for i = 1:num_iter
test1 = doWork1(struct1, struct2, selected_struct_str);
end
toc
tic
for i = 1:num_iter
test2 = doWork2(struct1, struct2, selected_struct_num);
end
toc
tic
for i = 1:num_iter
test3 = doWork3(struct, selected_struct_num);
end
toc
function data = doWork1(struct1, struct2, selected_struct)
data = eval([selected_struct '.data']);
end
function data = doWork2(struct1, struct2, selected_struct_num)
switch selected_struct_num
case 1
data = struct1.data;
case 2
data = struct2.data;
end
end
function data = doWork3(struct, selected_struct_num)
data = struct(selected_struct_num).data;
end
I am getting the following output:
>> eval_test
Elapsed time is 0.000418 seconds.
Elapsed time is 0.001516 seconds.
Elapsed time is 0.001594 seconds.
>> eval_test
Elapsed time is 0.000384 seconds.
Elapsed time is 0.001027 seconds.
Elapsed time is 0.001186 seconds.
>> eval_test
Elapsed time is 0.000558 seconds.
Elapsed time is 0.001280 seconds.
Elapsed time is 0.001304 seconds.
>> eval_test
Elapsed time is 0.000641 seconds.
Elapsed time is 0.001754 seconds.
Elapsed time is 0.001802 seconds.
>> eval_test
Elapsed time is 0.000357 seconds.
Elapsed time is 0.001117 seconds.
Elapsed time is 0.001430 seconds.
>> eval_test
Elapsed time is 0.000533 seconds.
Elapsed time is 0.001231 seconds.
Elapsed time is 0.001234 seconds.

Best Answer

  • Testing is tricky
    >> Untitled5
    Elapsed time is 0.167926 seconds.
    Elapsed time is 0.007457 seconds.
    Elapsed time is 0.010043 seconds.
    where Untitled5 is
    %%
    struct1.data = 2*ones(2);
    struct2.data = 4*ones(2);
    struct(1).data = 2*ones(2);
    struct(2).data = 4*ones(2);
    selected_struct_str = 'struct1';
    selected_struct_num = 1;
    num_iter = 1e4; % <<<<<<<<<<<<<<<<<<




    tic
    for i = 1:num_iter
    test1 = doWork1(struct1, struct2, selected_struct_str);
    end
    toc
    tic
    for i = 1:num_iter
    test2 = doWork2(struct1, struct2, selected_struct_num);
    end
    toc
    tic
    for i = 1:num_iter
    test3 = doWork3(struct, selected_struct_num);
    end
    toc
    function data = doWork1(struct1, struct2, selected_struct)
    data = eval([selected_struct '.data']);
    data = rand()*data; % <<<<<<<<<<<<<<<<<<
    end
    function data = doWork2(struct1, struct2, selected_struct_num)
    switch selected_struct_num
    case 1
    data = struct1.data;
    data = rand()*data; % <<<<<<<<<<<<<<<<<<
    case 2
    data = struct2.data;
    data = rand()*data; % <<<<<<<<<<<<<<<<<<
    end
    end
    function data = doWork3(struct, selected_struct_num)
    data = struct(selected_struct_num).data;
    data = rand()*data; % <<<<<<<<<<<<<<<<<<
    end
    ADDENDUM
    I converted the script to a function and left doWork-functions as subfunction. The elapse times didn't change much
    >> Untitled5
    Elapsed time is 0.171473 seconds.
    Elapsed time is 0.005879 seconds.
    Elapsed time is 0.010672 seconds.
    >> Untitled5
    Elapsed time is 0.172317 seconds.
    Elapsed time is 0.006429 seconds.
    Elapsed time is 0.010051 seconds.
    >>
    /R2018b