是A == 0比〜一个真正好? [英] Is A==0 really better than ~A?
问题描述
简介问题设置
我在做涉及一些基准 - 〜A
和 A == 0
为双阵列无提示NaN
,这两者的转换 A
来一个逻辑阵列,所有零
转换为真正
值和休息被设置为假
值。
有关的标杆,我使用的输入数据的三套 -
- 非常小,小型数据 -
15:5:100
- 中小型数据 -
50:40:1000
- 中到大型数据 -
200:400:3800
输入与 A = ROUND(RAND(N)* 20)创建
,其中N是从尺寸阵列拍摄的参数。因此, N
会从变化15至100为第一组,同样为第二和第三5
的步长集。请注意,我定义的数据大小为N,从而元素的数量将是数据大小^ 2或N ^ 2。
标杆code
N_arr = 15:5:100; //%非常小,以小尺寸输入数组
N_arr = 50:40:1000; //%为中小型输入数组
N_arr = 200:400:3800; //%为中到大型输入数组
timeall =零(2,numel(N_arr));
为K1 = 1:numel(N_arr)
A = ROUND(兰特(N_arr(K1))* 20); F = @()〜A;
timeall(1,K1)= timeit(六);
f清零 F = @()A == 0;
timeall(2,K1)= timeit(六);
f清零
结束
结果
最后的问题
我们可以看到 A == 0
性能比〜A
所有datasizes更好。因此,这里有一些意见和有关问题与他们并肩 -
-
A == 0
有一个关系运算符和一个操作数,而〜A
只有一个关系运算符。都产生逻辑阵列,并均接受双阵列。事实上,A == 0
将与的NaN
太,wheras〜A 工作code>不会。那么,为什么仍然
〜A
至少不如A == 0
,因为它看起来像A == 0
正在做更多的工作还是我失去了一些东西在这里? -
有经过的时间,一个奇特的下降
A == 0
,从而提高了性能在N = 320
在为答:我已经与大小上,我有机会获得两个不同的系统观察到这种在许多运行102400
元素。所以,这是怎么回事呢?
这不是严格意义上的答案,而是我在讨论中做
我用概述
来调查你的code的一个稍微修改后的版本:
N_arr = 200:400:3800; //%为中到大型输入数组为K1 = 1:numel(N_arr) A =兰迪(1 N_arr(K1));
[〜] = EQ(A,0);
一个清晰 A =兰迪(1 N_arr(K1));
[〜] =不(A);
一个清晰结束
我用下面的探查标志(按照 UndocumentedMatlab的约系列帖子概述
):
简介
曲线('上',' - 细节','内置');
下面是从探查结果(链接到较大的图像)的摘录:
看来, ==
变种分配更多的内存一点点,允许它的工作它的魔力......
关于你的问题2 :删除 timeall
的保持之前,我试图密谋在Excel中也做了同样的图表。我没有看到你的 N = 320
提到的行为。我怀疑这可能有一些与更多的封装做(即函数处理)你用你的code。
我想我会附上现有的文档为快速参考所讨论的功能。
为〜
文档(\\ MATLAB \\ R20 ??? \\工具箱\\ MATLAB \\ OPS \\ not.m):
%〜逻辑非。
%〜A执行输入数组A的逻辑非,并返回一个数组
设定为逻辑1(TRUE)含有%的元件或逻辑0(假)。
%输出阵列的元件被设置为1,如果A包含一个零值
以相同的数组位置%元素。否则,该元素被设定为
%0。
%
%B = NOT(A)被调用的语法'〜A'当A是一个对象。
%
%〜还可以用于以忽略在函数定义输入参数,
%和输出参数在函数调用。请参阅帮助PUNCT版权所有%1984 - 2005年MathWorks公司
为 ==文档
(\\ MATLAB \\ R20 ??? \\工具箱\\ MATLAB \\ OPS \\ eq.m):
%==等于。
%A == B中A和B之间的比较元素的元素呢
%和返回相同大小的设置为逻辑1的元素的矩阵
%,其中的关系是真实的元素设置为0逻辑它在哪里
未%。 A和B必须具有相同的尺寸,除非一个是
%标量。标量可以与任何大小的数组进行比较。
%
%C = EQ(A,B)被调用的语法A == B'时,A或B是
%的对象。版权所有%1984 - 2005年MathWorks公司
Introduction to problem setup
I was doing some benchmarks involving - ~A
and A==0
for a double array with no NaNs
, both of which convert A
to a logical array where all zeros
are converted to true
values and rest are set as false
values.
For the benchmarking, I have used three sets of input data –
- Very small to small sized data -
15:5:100
- Small to medium sized data -
50:40:1000
- Medium to large sized data -
200:400:3800
The input is created with A = round(rand(N)*20)
, where N is the parameter taken from the size array. Thus, N
would vary from 15 to 100 with stepsize of 5
for the first set and similarly for the second and third sets. Please note that I am defining datasize as N, thus the number of elements would be datasize^2 or N^2.
Benchmarking Code
N_arr = 15:5:100; %// for very small to small sized input array
N_arr = 50:40:1000; %// for small to medium sized input array
N_arr = 200:400:3800; %// for medium to large sized input array
timeall = zeros(2,numel(N_arr));
for k1 = 1:numel(N_arr)
A = round(rand(N_arr(k1))*20);
f = @() ~A;
timeall(1,k1) = timeit(f);
clear f
f = @() A==0;
timeall(2,k1) = timeit(f);
clear f
end
Results
Finally the questions
One can see how A==0
performs better than ~A
across all datasizes. So here are some observations and related questions alongside them –
A==0
has one relational operator and one operand, whereas~A
has only one relational operator. Both produce logical arrays and both accept double arrays. In fact,A==0
would work withNaNs
too, wheras~A
won’t. So, why is still~A
at least not as good asA==0
as it looks likeA==0
is doing more work or am I missing something here?There’s a peculiar drop of elapsed time with
A==0
and thus increased performance atN = 320
, i.e. at102400
elements for A. I have observed this across many runs with that size on two different systems that I have access to. So what’s going on there?
This is not strictly an answer but rather my contribution to the discussion
I used the profiler
to investigate a slightly-modified version of your code:
N_arr = 200:400:3800; %// for medium to large sized input array
for k1 = 1:numel(N_arr)
A = randi(1,N_arr(k1));
[~]=eq(A,0);
clear A
A = randi(1,N_arr(k1));
[~]=not(A);
clear A
end
I used the following profiler flags (as per UndocumentedMatlab's series of posts about Profiler
):
profile('-memory','on');
profile('on','-detail','builtin');
And here's an excerpt from the profiler results (link to the larger image):
It seems that the ==
variant allocates a tiny bit of additional memory that allows it to work its magic....
Regarding your question 2: Before removing the keeping of timeall
, I tried plotting the same charts you did in Excel. I didn't observe the behavior you mentioned for N = 320
. I suspect this may have something to do with the additional wrappers (i.e. function handles) you're using in your code.
I thought I'd attach the available documentation for the discussed functions for quick reference.
The documentation for ~
(\MATLAB\R20???\toolbox\matlab\ops\not.m):
%~ Logical NOT.
% ~A performs a logical NOT of input array A, and returns an array
% containing elements set to either logical 1 (TRUE) or logical 0 (FALSE).
% An element of the output array is set to 1 if A contains a zero value
% element at that same array location. Otherwise, that element is set to
% 0.
%
% B = NOT(A) is called for the syntax '~A' when A is an object.
%
% ~ can also be used to ignore input arguments in a function definition,
% and output arguments in a function call. See "help punct"
% Copyright 1984-2005 The MathWorks, Inc.
The documentation for ==
(\MATLAB\R20???\toolbox\matlab\ops\eq.m):
%== Equal.
% A == B does element by element comparisons between A and B
% and returns a matrix of the same size with elements set to logical 1
% where the relation is true and elements set to logical 0 where it is
% not. A and B must have the same dimensions unless one is a
% scalar. A scalar can be compared with any size array.
%
% C = EQ(A,B) is called for the syntax 'A == B' when A or B is an
% object.
% Copyright 1984-2005 The MathWorks, Inc.
这篇关于是A == 0比〜一个真正好?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!