克隆是写时复制吗?

Is clone copy-on-write?

当我使用 clone 运算符克隆 Imagick 对象时,哪个是昂贵的操作,clone 或后续写入克隆?

$image = new Imagick();
$image->readImage('some_big_image.jpg');

$new_image = clone $image; // is this an expensive operation?

是的,Imagick 对象上的克隆方法确实在做实际工作,而不是仅仅增加一个内部引用计数器。

特别是它在底层 ImageMagick 库中调用 CloneMagickWand。这确实复制了 'image' - 但是 ImageMagick 并不总是将图像的所有像素保存在内存中。所以它到底做了多少工作并不明显,可能取决于你如何配置 ImageMagick。

后续写入的开销将取决于所使用的功能。在保存图像之前,为图像设置新格式并没有多大用处。对图像进行模糊处理(显然)需要大量工作。

在 Windows 7 上使用 ImageMagick 6.8.9 构建的 Imagick 3.3.0RC2 进行的一些测试给出了这些结果:

$image = new Imagick();
$image->setResolution(1000,1000);

// This is a vector image, to make sure it's not just memory-mapped or something like that
$image->readImageBlob(file_get_contents(__DIR__.'/test.eps'));

$new_image = clone $image;                                         // 0.012 s  
$new_image->floodFillPaintImage('black', 0, 'white', 0, 0, false); // 0.179 s
$image->floodFillPaintImage('black', 0, 'white', 0, 0, false);     // 0.126 s

(我运行这是一个循环,给定的持续时间是平均的。)

从这些数字看来 clone 与后续写入相比非常便宜。