更多关于在Matlab中使用i和j作为变量:速度

Lui*_*ndo 11 performance matlab complex-numbers

Matlab的文件说,

为了提高速度和改进稳健性,您可以将复杂的i和j替换为1i.例如,而不是使用

a = i;
Run Code Online (Sandbox Code Playgroud)

使用

a = 1i;
Run Code Online (Sandbox Code Playgroud)

鲁棒性的部分是清楚的,因为有可能被称为变量ij.但是,至于速度,我在Matlab 2010b中做了一个简单的测试,我得到的结果似乎与索赔相矛盾:

>>clear all

>> a=0; tic, for n=1:1e8, a=i; end, toc
Elapsed time is 3.056741 seconds.

>> a=0; tic, for n=1:1e8, a=1i; end, toc
Elapsed time is 3.205472 seconds.
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?它可能是版本相关的问题吗?

经过@TryHard和@horchler的评论后,我尝试为变量分配其他值a,结果如下:

增加经过时间的顺序:

"i"<"1i"<"1*i"(趋势"A")

"2i"<"2*1i"<"2*i"(趋势"B")

"1 + 1i"<"1 + i"<"1 + 1*i"(趋势"A")

"2 + 2i"<"2 + 2*1i"<"2 + 2*i"(趋势"B")

She*_*tJS 11

我想你正在看一个病态的例子.尝试更复杂的东西(在OSX上显示R2012b的结果):

(重复添加)

>> clear all
>> a=0; tic, for n=1:1e8, a = a + i; end, toc
Elapsed time is 2.217482 seconds. % <-- slower
>> clear all
>> a=0; tic, for n=1:1e8, a = a + 1i; end, toc
Elapsed time is 1.962985 seconds. % <-- faster
Run Code Online (Sandbox Code Playgroud)

(重复乘法)

>> clear all
>> a=0; tic, for n=1:1e8, a = a * i; end, toc
Elapsed time is 2.239134 seconds. % <-- slower
>> clear all
>> a=0; tic, for n=1:1e8, a = a * 1i; end, toc
Elapsed time is 1.998718 seconds. % <-- faster
Run Code Online (Sandbox Code Playgroud)

  • "尝试一些更复杂的东西......" - 我希望 - 我想要的.:-) (14认同)

Amr*_*mro 6

需要记住的一点是,无论是从命令行还是保存的M函数运行,都会以不同的方式应用优化.

这是我自己的测试:

function testComplex()
    tic, test1(); toc
    tic, test2(); toc
    tic, test3(); toc
    tic, test4(); toc
    tic, test5(); toc
    tic, test6(); toc
end

function a = test1
    a = zeros(1e7,1);
    for n=1:1e7
        a(n) = 2 + 2i;
    end
end

function a = test2
    a = zeros(1e7,1);
    for n=1:1e7
        a(n) = 2 + 2j;
    end
end
function a = test3
    a = zeros(1e7,1);
    for n=1:1e7
        a(n) = 2 + 2*i;
    end
end

function a = test4
    a = zeros(1e7,1);
    for n=1:1e7
        a(n) = 2 + 2*j;
    end
end

function a = test5
    a = zeros(1e7,1);
    for n=1:1e7
        a(n) = complex(2,2);
    end
end

function a = test6
    a = zeros(1e7,1);
    for n=1:1e7
        a(n) = 2 + 2*sqrt(-1);
    end
end
Run Code Online (Sandbox Code Playgroud)

在运行R2013a的Windows机器上的结果:

>> testComplex
Elapsed time is 0.946414 seconds.    %// 2 + 2i
Elapsed time is 0.947957 seconds.    %// 2 + 2j
Elapsed time is 0.811044 seconds.    %// 2 + 2*i
Elapsed time is 0.685793 seconds.    %// 2 + 2*j
Elapsed time is 0.767683 seconds.    %// complex(2,2)
Elapsed time is 8.193529 seconds.    %// 2 + 2*sqrt(-1)
Run Code Online (Sandbox Code Playgroud)

请注意,结果会随着调用顺序的不同运行而稍微波动.所以,时间与一粒盐.

我的结论:如果你使用1i或者速度方面无关紧要1*i.


一个有趣的区别是,如果你在函数范围内也有一个变量,你也将它用作虚数单元,那么MATLAB会抛出一个错误:

Error: File: testComplex.m Line: 38 Column: 5
"i" previously appeared to be used as a function or command, conflicting with its
use here as the name of a variable.
A possible cause of this error is that you forgot to initialize the variable, or you
have initialized it implicitly using load or eval.
Run Code Online (Sandbox Code Playgroud)

要查看错误,请将以上test3功能更改为:

function a = test3
    a = zeros(1e7,1);
    for n=1:1e7
        a(n) = 2 + 2*i;
    end
    i = rand();        %// added this line!
end
Run Code Online (Sandbox Code Playgroud)

即,该变量i在同一局部范围内用作函数和变量.

  • 是的,我测量时间的方式不是很准确.更好的解决方案是使用文件交换中的[TIMEIT](http://www.mathworks.com/matlabcentral/fileexchange/18798-timeit-benchmarking-function),它负责预热代码,多次运行并且平均结果,同时考虑到调用函数的开销......你会很高兴地知道下一个版本的MATLAB(知道的预发行版)原生包含这个函数! (3认同)
  • 我打赌如果你在计时之前"预热"这些功能,任何差异都会消失在噪音中. (2认同)