Compiler construction 是否有任何编译器/解释器可以优化未到位到到位的操作?

Compiler construction 是否有任何编译器/解释器可以优化未到位到到位的操作?,compiler-construction,interpreter,vectorization,compiler-optimization,in-place,Compiler Construction,Interpreter,Vectorization,Compiler Optimization,In Place,当我给论文评分时,我经常观察到这样的错误(当然有时我自己也会这样做): %任何支持逻辑索引的矢量化语言,如MATLAB/Octave/R Y=兰特(1,10);%从1x10向量的区间[0,1]均匀抽取的随机数 Y(Y0.6)=0;%这两条线试图将分布从均匀分布转换为伯努利分布 该代码生成一个零向量,而不是期望的随机二进制向量,其分布近似于伯努利随机变量 从编程的角度来看,问题在于就地修改;编码员跳过了一个思维步骤。(还有其他方法可以解决这个问题,基于代码应该完成的数学,或者通过切换条件等,但这

当我给论文评分时,我经常观察到这样的错误(当然有时我自己也会这样做):

%任何支持逻辑索引的矢量化语言,如MATLAB/Octave/R
Y=兰特(1,10);%从1x10向量的区间[0,1]均匀抽取的随机数
Y(Y0.6)=0;%这两条线试图将分布从均匀分布转换为伯努利分布
该代码生成一个零向量,而不是期望的随机二进制向量,其分布近似于伯努利随机变量

从编程的角度来看,问题在于就地修改;编码员跳过了一个思维步骤。(还有其他方法可以解决这个问题,基于代码应该完成的数学,或者通过切换条件等,但这些都是特定于应用程序的。)单元测试可以将错误暴露出来,但我无法说服任何学生尝试它们(具体来说,这不是编程课)。首先分配输出向量并根据输入向量填充它的代码可以防止这种情况发生:

X = rand(1,10); % random numbers in a 1x10 vector
Y = zeros(size(X));
Y(X<=0.6) = 1;
Y(X>0.6) = 0;
X=rand(1,10);%1x10向量中的随机数
Y=零(尺寸(X));
Y(X0.6)=0;
然而,这肯定会占用两倍的空间,尽管我想说它更适合这里错误的编码者的心理模型,并且通常比一个完全不浪费空间的真正复杂的算法更容易理解(参见快速排序的CLRS说明)


是否有任何编译器/解释器可以优化代码(如第二个代码段)以将所需空间减少到就地操作的空间?

是的,有。在您讨论的领域中有一些不同的优化:

    < > >许多C++编译器会避免创建一个新的临时对象,只需立即复制它,就可以立即复制它。

  • LuaJIT和其他一些编译器所做的工作可能与您的想法类似

  • 同样的道理


过早优化是万恶之源,额外的存储真的很重要吗?不是10点,不是,但是如果是一个1000万点的输入和嵌入式系统的生产代码,我想要一个谨慎的习惯或一个能够优化这种空间使用的编译器。当然。想象一个Fortran编译器计算a=a+B,其中a和B是巨大的矩阵。这个简单的实现是T=A+B;A=T对T浪费了大量的空间。但是,编译器进行生存期分析时,可以意识到“旧A”已经死了,并将空间重新用于新A。这在面向数组的Fortran编译器中非常常见。问题是,对于某些问题,您需要一种完全不同的算法来降低空间成本。通常,编译器优化不会从根本上重写算法。在简单的情况下,可以完成Ira Baxter的示例(这可以通过语言设计进一步简化,例如线性键入)。但在您的示例中,
X
不能用于
Y
,因为它们的生命周期重叠,为了消除这种情况,编译器必须找出如何合并这两个语句
Y(X1)=0
同时确保以后不会访问被重用的
X
插槽。那么您认为Ira提到的生命周期分析是比较常见的,并且可能是您所期望的最好的?
X = rand(1,10); % random numbers in a 1x10 vector
Y = zeros(size(X));
Y(X<=0.6) = 1;
Y(X>0.6) = 0;