ITK Filter在C++中比Python慢



我使用SimpleITK在Python中制作了一个模块,我试图通过在C++中重新实现来加快速度。结果它慢了很多。

瓶颈是位移字段雅可比行列式过滤器的使用。

这两个片段给出了过滤器使用的示例。

1000代:C++=55s,python=8s

我应该期待c++更快吗?

def test_DJD(label_path, ngen):
  im = sitk.ReadImage(label_path)
  for i in range(ngen):
    jacobian = sitk.DisplacementFieldJacobianDeterminant(im)

 if __name__ == '__main__':

    label = sys.argv[1]
    ngen = int(sys.argv[2])
    test_DJD(label, ngen)

和c++代码

typedef itk::Vector<float, 3> VectorType;
typedef itk::Image<VectorType, 3> VectorImageType;
typedef itk::DisplacementFieldJacobianDeterminantFilter<VectorImageType >  JacFilterType;
typedef itk::Image<float, 3> FloatImageType;

int main(int argc, char** argv) {
std::string idealJacPath = argv[1];
std::string numGensString = argv[2];
int numGens;
istringstream ( numGensString ) >> numGens;

typedef itk::ImageFileReader<VectorImageType> VectorReaderType;
VectorReaderType::Pointer reader=VectorReaderType::New();
reader->SetFileName(idealJacPath);
reader->Update();
VectorImageType::Pointer vectorImage=reader->GetOutput();

JacFilterType::Pointer jacFilter = JacFilterType::New();
FloatImageType::Pointer generatedJac = FloatImageType::New();
for (int i =0; i < numGens; i++){
    jacFilter->SetInput(vectorImage);
    jacFilter->Update();
    jacFilter->Modified();
    generatedJac = jacFilter->GetOutput();
}
return 0;
}

我使用的是c++ITK 4.8.2,在Ubuntu 15.4上以"发布"模式编译。和python SimpleITK v9.0

您似乎在使用循环进行基准测试。使用循环进行基准测试不是一种好的做法,因为编译器和解释器对它们进行了大量优化。

我相信在这里

for i in range(ngen):
    jacobian = sitk.DisplacementFieldJacobianDeterminant(im)

python解释器很可能意识到,您只使用了分配给jacobian变量的最后一个值,因此只执行循环的一次迭代。这是一个非常常见的循环优化。

另一方面,由于您在C++版本(jacFilter->Update();)中调用了几个动态方法,编译器可能无法推断其他调用没有被使用,这使得您的C++版本变慢,因为对DisplacementFieldJacobianDeterminant::update方法的所有调用都是实际进行的。

另一个可能的原因是Python中的ITK管道没有被强制更新,因为您在C++中显式地调用了jacFilter->Modified(),但这在Python版本中并不显式。

最新更新