我使用SimpleITK在Python中创建了一个模块,我试图通过在C ++中重新实现来加快速度。事实证明它要慢得多。
瓶颈是使用DisplacementFieldJacobianDeterminantFilter。
这两个片段给出了过滤器用法的示例。
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并在&#39;发布&#39; Ubuntu 15.4上的模式。和python SimpleITK v 9.0
答案 0 :(得分:0)
您似乎使用循环进行基准测试。使用循环进行基准测试不是一个好习惯,因为编译器和解释器对它们进行了很多优化。
我相信在这里
for i in range(ngen):
jacobian = sitk.DisplacementFieldJacobianDeterminant(im)
python解释器很可能意识到你只使用分配给jacobian
变量的最后一个值,因此只执行循环的一次迭代。这是一种非常常见的循环优化。
另一方面,由于您在C ++版本中调用了几个动态方法(jacFilter->Update();
),编译器可能无法推断其他调用未被使用,从而使您的C ++版本变慢因为实际上对DisplacementFieldJacobianDeterminant :: update方法进行了所有调用。
另一个可能的原因是Python中的ITK管道没有被强制更新,因为你在C ++中显式调用了jacFilter->Modified()
,但这在Python版本中并不明确。