Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/laravel/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 为什么在Matlab中,在某些情况下,对于标量,*运算符比*更快?_Performance_Matlab - Fatal编程技术网

Performance 为什么在Matlab中,在某些情况下,对于标量,*运算符比*更快?

Performance 为什么在Matlab中,在某些情况下,对于标量,*运算符比*更快?,performance,matlab,Performance,Matlab,考虑以下代码: a=rand(10000); b=rand(10000); tic; 2*(a<b); toc; tic; 2.*(a<b); toc; 为什么第二种情况比第一种情况快两倍 编辑: 对于任意大小的矩阵,无论测试的顺序如何,我都会得到相同的结果 (a<b).*3.56 vs (a<b)*3.56 或 似乎有一个与逻辑数组的链接,因为我与 (a&b)*2 vs (a&b).*2 计算机:R2015b,Windows 10 x64我

考虑以下代码:

a=rand(10000); b=rand(10000);
tic; 2*(a<b); toc;
tic; 2.*(a<b); toc;    
为什么第二种情况比第一种情况快两倍

编辑: 对于任意大小的矩阵,无论测试的顺序如何,我都会得到相同的结果

(a<b).*3.56 vs (a<b)*3.56

似乎有一个与逻辑数组的链接,因为我与

(a&b)*2 vs (a&b).*2

计算机:R2015b,Windows 10 x64我建议对性能进行更严格的检查。将您的测试放在一个命名函数中,让MATLAB优化这两段代码,并运行这两段代码数次,选择最快的运行时。我的直觉是,它们应该花费相同的时间,尽管我现在无法用合理的矩阵大小进行检查。下面是我要做的:

function product_timing(N)

a=rand(N);
b=rand(N);

tmin=inf;
for k=1:10
    tic;
    res1=2*(a<b);
    t=toc;
    
    if t<tmin
        tmin=t;
    end
end

disp(tmin);


tmin=inf;
for k=1:10
    tic;
    res2=2.*(a<b);
    t=toc;
    
    if t<tmin
        tmin=t;
    end
end
功能产品\u定时(N)
a=兰特(N);
b=兰特(N);
tmin=inf;
对于k=1:10
抽搐;
res1=2*(aYes,“.*”在2015b标量和逻辑数组之间更快:

a = rand(10000); b = rand(10000);
timeit(@()2*a)
timeit(@()2.*a)

timeit(@()2.*(a>b))
timeit(@()2*double(a>b))
timeit(@()2*(a>b))

作为背景,
*
运算符是矩阵运算符,而
*。
是元素运算符(请参阅)

在您的测试中,a和b是随机的1000x1000矩阵,它们评估为逻辑的1000x1000矩阵,您需要使用这两种方法进行缩放。除了让Mathworks的开发人员告诉我们在下面发生了什么,我认为我们只能推测是什么导致了差异(并回答您的问题)

既然我们不应该对这些答案进行推测,我就正式到此为止。然而,你所发现的同样有趣

因此,非正式地说,我怀疑您已经发现MATLAB正在实现一些额外的开销,用
*
运算符处理矩阵运算,这些运算在元素运算符中被短路或绕过

考虑以下几点

c = a<b;
tic; d*(c); toc;  % case 1
tick;d.*(c); toc; % case 2

c=aI在R2015b、Win10 x64(k从1到100)上得到不同的结果:乘积_计时(10000)0.8183(1)0.2113(2)差异比以前大。@x1hgg1x哇,有趣:)关于
N=1000
?这应该与我的比较相当(不幸的是,我现在没有足够的空闲内存来测试您的测试用例)。另外:您应该尝试交换这两种类型代码的顺序,以便首先使用
*
。我希望这不会改变结果,但在R2015b中,各种各样的优化魔法都会发生。@x1hgg1x也会发生
(a@AndrasDeak:绝对不是
(2)*
不是运算符,它是文本的一部分。这将违反任何常见的编程语言的工作方式。我找不到一个乘法示例,您可以看到其中的区别,但是
2。^magic(3)
(2.)^magic(3)
用power来演示。@AndrasDeak:乘法的另一个例子:
x=serial('com1');2.*x;
。错误消息告诉您函数名。您得到了什么结果?我用代码得到的顺序是:1)0.3137,2)0.3135,3)0.5059,4)0.8972,5)0。9708@x1hgg1x,这就是我为什么说“*”在你和Andras DeakYou还应该检查
(uint8(a)*2
vs
(uint8(a)).*2
之前,标量数组和逻辑数组之间的速度更快。这可能不是布尔性,而是整数性。而且,
c=a与
(uint8(a)*2
vs
(uint8(a)没有区别*2
,但我看到了
c=aThanks与
c=aThanks的相同区别。对于所有反馈,我已经用额外的信息更新了我的答案。我仍然没有得到明确的答案,但可能只有mathworks员工可以给出一个答案。但您的发现也意味着,对于标量输入,可能
mtimes
应该依赖
时间。感谢您的接受,尽管我不太确定我是否回答了您的问题:)无论如何,您可以尝试使用未记录的功能(请参阅www.undocumentedmatlab.com/blog/undocumented feature function)
功能('JIT','off')
功能('accel','off')
,也许可以清楚提速的来源(假设
'JIT'
案例修改
'accel'
案例的一个子集。)您的解释很有趣,但只有当c是逻辑数组时才有区别(请参见我的编辑)。这很有趣-感谢您的后续编辑。@x1hgg1x是的,您可以对不同的操作计时,但我认为我们无法回答您关于“为什么”的问题这种情况下,不必看引擎盖下的情况。不过,看到您如何能够更好地描述下面的处理方式,尤其是逻辑阵列结果(例如
function product_timing(N)

a=rand(N);
b=rand(N);

tmin=inf;
for k=1:10
    tic;
    res1=2*(a<b);
    t=toc;
    
    if t<tmin
        tmin=t;
    end
end

disp(tmin);


tmin=inf;
for k=1:10
    tic;
    res2=2.*(a<b);
    t=toc;
    
    if t<tmin
        tmin=t;
    end
end
a = rand(10000); b = rand(10000);
timeit(@()2*a)
timeit(@()2.*a)

timeit(@()2.*(a>b))
timeit(@()2*double(a>b))
timeit(@()2*(a>b))
c = a<b;
tic; d*(c); toc;  % case 1
tick;d.*(c); toc; % case 2