Nginx初步-5:用SWIG为PHP写个C++的扩展

来源:互联网 发布:淘宝管理平台收费 编辑:程序博客网 时间:2024/06/16 07:29

PHP-GD的性能

在写这章之前,先运行一段PHP脚本。如下:

$src = "test.jpg"; // 图像优化里用到的图片$dst = "upload/gray.jpg"; // 保存的结果$totalTime = 0;$testCount = 32; // 只能用这么小的值,否则运行超过30秒$count = 0;// 尝试使用PHP-GDfor($i = 0; $i < $testCount; $i++){$start = getNanos();$im = imagecreatefromjpeg($src);imagefilter($im, IMG_FILTER_GRAYSCALE);imagegd($im, $dst);imagedestroy($im);$stop = getNanos();$time = (max($start, $stop) - min($start, $stop)) / (1000 * 1000);if ($time > 500.0){//continue;}else{$count++;$totalTime += $time;}}if ($count == 0)$count = 1;echo "Perf:" . $totalTime / $count . "ms<br />";

先不要管getNano(),这个在后面会给出实现。这段程序运行的结果表明,对于test.jpg这样图片处理,GD需要差不多半秒。这个性能不能说很差,毕竟对大图的直接操作很少见。但想想《图像处理的简单优化》中得出的结果,GD还是很不给力。所以,就需要将快速的处理引入到PHP中,也就需要用到swig了。


编写PHP的扩展,提升性能

毫无疑问,这个扩展要命名为igame。

仿照GD的函数,简单定义了swig的接口文件,如下所示:

%module igame%include <const.i>%include <std_string.i>%{#include "igame.h"#include "image.h"unsigned int getNanos();int grayscaleJpeg(char* src, char* dst);Image* createImageFromJpeg(const std::string& filename);Image* createImageJpeg(unsigned int width, unsigned int height);int applyImageEffect(Image* img);int imageSaveAsJpeg(Image* img, const std::string& filename);void destroyImage(Image* img);%}extern unsigned int getNanos();extern int grayscaleJpeg(char* src, char* dst);class Image{public:Image();Image(unsigned int width, unsigned int height);Image(const std::string& filename);virtual ~Image();public:virtual bool create(unsigned int width, unsigned int height);virtual bool save(const std::string& filename) = 0;virtual bool load(const std::string& filename) = 0;virtual bool close();virtual bool available();virtual unsigned int width();virtual unsigned int height();virtual unsigned int stride();virtual unsigned int bytesPerPixel();virtual bool applyEffect(Effect* effect);}; // classextern Image* createImageFromJpeg(const std::string& filename);extern Image* createImageJpeg(unsigned int width, unsigned int height);extern int applyImageEffect(Image* img);extern int imageSaveAsJpeg(Image* img, const std::string& filename);extern void destroyImage(Image* img);

注意,这里的Image类导出有问题,无法调用类的方法。后续再处理吧,现在用做容器还是可以的。

实现文件如下:

igame.h

#ifndef IGAME_H#define IGAME_H#include "image.h"unsigned int getNanos();int grayscaleJpeg(char* src, char* dst);Image* createImageFromJpeg(const std::string& filename);Image* createImageJpeg(unsigned int width, unsigned int height);int applyImageEffect(Image* img);int imageSaveAsJpeg(Image* img, const std::string& filename);void destroyImage(Image* img);#endif
igame.cpp

#include "igame.h"#include "jpeg.h"#include "grayscale.h"#include <time.h>unsigned int getNanos(){struct timespec time;clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time);return time.tv_sec * 1000 * 1000 + time.tv_nsec;}int grayscaleJpeg(char* src, char* dst){Jpeg myjpg;if (myjpg.load(src)){Grayscale grayscale;if (myjpg.applyEffect(&grayscale)){if (myjpg.save(dst))return true;}}return false;}Image* createImageFromJpeg(const std::string& filename){return new Jpeg(filename);}Image* createImageJpeg(unsigned int width, unsigned int height){return new Jpeg(width, height);}int applyImageEffect(Image* img){Grayscale grayscale;return img->applyEffect(&grayscale);}int imageSaveAsJpeg(Image* img, const std::string& filename){return img->save(filename);}void destroyImage(Image* img){delete img;}

修改PHP.INI,使之能够使用扩展包。再编写相同的测试页面,最后得出结果:136.494ms。大致是GD的3倍多。

相较于GD的可怜性能,这才是自己开发扩展的用意。


完整的eclipse工程可以从这里下载。

0 0
原创粉丝点击