Java Null检查消除可能导致错误的代码?(Java Null check elimination can cause bad code?)
最近,我在这里阅读有关JVM优化的内容,这些内容很棒,
但我有一个优化的问题,即空检查消除 (或罕见陷阱)总结Null Check Elimination删除
if (obj == null) ...
并希望获得最佳,而如果遇到Segmentation Fault则重新编译代码,这次包括被忽略的if (obj == null) ...
。我的问题是,鉴于:
bool foo(MyClass obj) { if(obj == null) return false; m_someVar++; obj.doSomething(m_someVar); }
因为Null-Check被删除了,只有在
m_someVar++
之后m_someVar++
需要。
当c为空时,foo会执行m_someVar++
吗?编辑:
是否有一些来源可以更深入地解释这种优化的实现,这解释了这种优化如何保持代码在语义上相同?
谢谢
Recently, I read here about JVM optimizations , which are great,
but i have a problem with one optimization, namely Null Check Elimination (or Uncommon trap)To sum up Null Check Elimination removes a
if (obj == null) ...
and hopes for the best, while if encounters a Segmentation Fault it recompiles the code and this time includes the neglectedif (obj == null) ...
.My question is, Given:
bool foo(MyClass obj) { if(obj == null) return false; m_someVar++; obj.doSomething(m_someVar); }
because the Null-Check is eliminated, and required only after
m_someVar++
.
will foo executem_someVar++
an extra time when c will be null?Edit:
Is there some source for deeper explanation on the implementation of this optimizations, which explain how does this optimization keeps the code semantically same?
Thanks
原文:https://stackoverflow.com/questions/46043185
最满意答案
这是我写的测试,输出说明了事实。 cv :: Sobel计算相关性而不是卷积。 我使用了以下与cv :: Sobel使用的内核相同的内核
kern = [-1, 0, 1; -2, 0, 2; -1, 0, 1]
结果显示sobelx和filter2d(相关)的输出是相同的。
void test_sobel(){ cv::RNG(0); cv::Mat src(4,4, CV_8U); cv::randu(src, 0, 256); cv::Mat sobelx, dest_corr,dest_conv; cv::Sobel(src, sobelx, CV_32F,1,0,3); // sobel uses a 3x3 filter shown as below Mat kern = (Mat_<float>(3,3)<<-1,0,1,-2,0,2,-1,0,1); // filter2D computes correlation cv::filter2D(src,dest_corr,CV_32F,kern); //flip the kernel in x and y direction for convolution cv::Mat kern_conv; cv::flip(kern,kern_conv, -1); cv::filter2D(src,dest_conv,CV_32F,kern_conv); std::cout << "kern = \n" << kern<< std::endl; std::cout << "kern_conv = \n" << kern_conv<< std::endl; std::cout << "src = \n" << src << std::endl; std::cout << "sobelx = \n" << sobelx<< std::endl; std::cout << "dest_corr = \n" << dest_corr<< std::endl; std::cout << "dest_conv =\n" << dest_conv << std::endl; cv::Mat diff1 = sobelx - dest_corr; cv::Mat diff2 = sobelx - dest_conv; std::cout << "sobelx - dest_corr = " << cv::sum( diff1 )[0] << std::endl; std::cout << "sobelx - dest_conv = " << cv::sum( diff2 )[0] << std::endl; }
输出:
kern = [-1, 0, 1; -2, 0, 2; -1, 0, 1] kern_conv = [1, 0, -1; 2, 0, -2; 1, 0, -1] src = [246, 156, 192, 7; 165, 166, 2, 179; 231, 212, 171, 230; 93, 138, 123, 80] sobelx = [0, -434, -272, 0; 0, -440, -105, 0; 0, -253, -9, 0; 0, -60, -80, 0] dest_corr = [0, -434, -272, 0; 0, -440, -105, 0; 0, -253, -9, 0; 0, -60, -80, 0] dest_conv = [0, 434, 272, 0; 0, 440, 105, 0; 0, 253, 9, 0; 0, 60, 80, 0] sobelx - dest_corr = 0 sobelx - dest_conv = -3306
Here is the test that i wrote and the output tells the truth. cv::Sobel computes correlation and not convolution. I have used the following kernel which is the same as used by cv::Sobel
kern = [-1, 0, 1; -2, 0, 2; -1, 0, 1]
The results show that the output of sobelx and filter2d(correlation) is same.
void test_sobel(){ cv::RNG(0); cv::Mat src(4,4, CV_8U); cv::randu(src, 0, 256); cv::Mat sobelx, dest_corr,dest_conv; cv::Sobel(src, sobelx, CV_32F,1,0,3); // sobel uses a 3x3 filter shown as below Mat kern = (Mat_<float>(3,3)<<-1,0,1,-2,0,2,-1,0,1); // filter2D computes correlation cv::filter2D(src,dest_corr,CV_32F,kern); //flip the kernel in x and y direction for convolution cv::Mat kern_conv; cv::flip(kern,kern_conv, -1); cv::filter2D(src,dest_conv,CV_32F,kern_conv); std::cout << "kern = \n" << kern<< std::endl; std::cout << "kern_conv = \n" << kern_conv<< std::endl; std::cout << "src = \n" << src << std::endl; std::cout << "sobelx = \n" << sobelx<< std::endl; std::cout << "dest_corr = \n" << dest_corr<< std::endl; std::cout << "dest_conv =\n" << dest_conv << std::endl; cv::Mat diff1 = sobelx - dest_corr; cv::Mat diff2 = sobelx - dest_conv; std::cout << "sobelx - dest_corr = " << cv::sum( diff1 )[0] << std::endl; std::cout << "sobelx - dest_conv = " << cv::sum( diff2 )[0] << std::endl; }
Output:
kern = [-1, 0, 1; -2, 0, 2; -1, 0, 1] kern_conv = [1, 0, -1; 2, 0, -2; 1, 0, -1] src = [246, 156, 192, 7; 165, 166, 2, 179; 231, 212, 171, 230; 93, 138, 123, 80] sobelx = [0, -434, -272, 0; 0, -440, -105, 0; 0, -253, -9, 0; 0, -60, -80, 0] dest_corr = [0, -434, -272, 0; 0, -440, -105, 0; 0, -253, -9, 0; 0, -60, -80, 0] dest_conv = [0, 434, 272, 0; 0, 440, 105, 0; 0, 253, 9, 0; 0, 60, 80, 0] sobelx - dest_corr = 0 sobelx - dest_conv = -3306
相关问答
更多-
Sobel在OpenCV中的衍生产品(Sobel derivative in OpenCV)[2023-08-24]
此代码片段演示了如何计算使用Sobel内核对图像进行卷积的Sobel 3x3衍生产品。 您可以轻松扩展到不同的内核大小,将内核半径作为my_sobel输入,并创建适当的内核。 #include#include using namespace std; using namespace cv; void my_sobel(const Mat1b& src, Mat1s& dst, int direction) { Mat1s kern ... -
好吧,那么我已经找到了解决方案,以防任何人想使用相同的算法; cv::Mat src = cv::imread("C:/Users/Cihan/Desktop/aa.png"); cv::Mat src_gray; cvtColor(src, src_gray, CV_BGR2GRAY); cv::Mat grad_x; cv::Mat grad_y; int d ...
-
更新 : 更好的方法。 #!/usr/bin/python3 # 2017.12.22 21:48:22 CST import cv2 import numpy as np ## parameters sobelX = np.array([[1,0,-1],[2,0,-2],[1,0,-1]]) sobelY = sobelX.T ddepth = cv2.CV_16S ## calc gx and gy #img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) img ...
-
这是我写的测试,输出说明了事实。 cv :: Sobel计算相关性而不是卷积。 我使用了以下与cv :: Sobel使用的内核相同的内核 kern = [-1, 0, 1; -2, 0, 2; -1, 0, 1] 结果显示sobelx和filter2d(相关)的输出是相同的。 void test_sobel(){ cv::RNG(0); cv::Mat src(4,4, CV_8U); cv::randu(src, 0, 256); cv::Mat sobelx, dest ...
-
知道了,只需像这样使用cv2.filter2D : import numpy as np import cv2 mx = np.array([[-1, 0, 1]]) my = np.array([[-1, 0, 1]]).T im = np.array([[1, 2, 3, 4, 5], [2, 3, 4, 5, 6], [3, 4, 5, 6, 7], [4, 5, 6, 7, 8], ...
-
我认为这个片段可以解决问题: def gradient(img, dx, dy, ksize): deriv_filter = cv2.getDerivKernels(dx=dx, dy=dy, ksize=ksize, normalize=True) return cv2.sepFilter2D(img, -1, deriv_filter[0], deriv_filter[1]) I think this snippet will do the trick: def gradient(i ...
-
好吧,我发现了错误。 我的代码有三个问题: 1)在show_angle函数中,numpy运算符应该大于等于并小于或等于比较。 2)在用来将rads转换为度数的公式中,我没有用pi分割。 3)我应该将numpy矩阵转换为uint8类型。 更正的代码: import cv2 import numpy as np import matplotlib.pyplot as plt import math def show_image(name, img, waitkey=0): cv2.namedWi ...
-
最好是直接计算这两个Mat文件的特征向量的相关性,而不是Mat数据。 例如,您可以先为每个Mat文件计算RGB / HSV颜色直方图(24d向量,如果每个通道使用8个bin),然后计算这两个直方图向量的相关性。 It's better to compute the correlation of feature vectors of these two Mat files instead of on the Mat data directly. For example, you can first compu ...
-
如果您只需要渐变的绝对值,而不进行任何规范化,则可以使用cv::convertScaleAbs() 。 这将找到绝对值并一次性转换为8位无符号类型。 cv::Mat dx, dy; cv::Sobel(img, dx, CV_16S, 1, 0); cv::Sobel(img, dy, CV_16S, 0, 1); cv::convertScaleAbs(dx, dx); cv::convertScaleAbs(dy, dy); 请注意,此方法仅计算导数的绝对值,并且不会将结果标准化为[0, 255] 。 ...
-
使用Java中的OpenCV 2.4.10在jpg图片上应用sobel滤镜(Applying sobel filter on jpg picture with OpenCV 2.4.10 in Java)[2022-03-08]
首先,有没有你不使用的原因 Imgproc.Sobel(Mat src, Mat dst, int ddepth, int dx, int dy); 我不确定这里使用的Java语法。 什么时候执行块的执行? 它是否被假定为您定义的Mat子类的构造函数的一部分? 话虽如此,假设这样做的目的是它的意图,那么你的输出文件类型可能没有正确指定; destinationPath的价值是什么? 您是否尝试在备用图像查看器中打开已保存的文件以确定它是ShowImage()代码还是保存的错误文件? 您是否尝试在十六进制编 ...