2009年02月26日

-0.4.2版本的代码有3480行,而图形界面的星际译王更是有N多的代码,俺也写了一个就十几行的代码,速度当然比不上,能差十倍,不过,请注意,查一个单词是0.01秒,我这个是0.1秒,我不觉得有人能感觉出来差别。

其实我的核心是C语言写的,之所以在速度上没有快是没有做那么些优化,俺只写了80多行,而且还有不少代码是用作封装的。我以前写文章说过代码写的很麻烦,用C语言可以很简洁的写出来,现在确实做到了,只是结合了。我觉得这种模式挺不错,影响速度的核心使用C语言去写,然后主逻辑框架使用写,不仅效率不会受影响,开发的速度也提高了不少。(我这个例子并没做什么)

C:
  1. static PyObject * lookup(PyObject *self, PyObject *args)
  2. {
  3.     int fd;
  4.     char *file_prefix;
  5.     long file_size;
  6.     long wc;
  7.     char *word;
  8.  
  9.     char *data;
  10.     const char *p;
  11.     long index_size;
  12.     int offset;
  13.     int size;
  14.     int flag = 0;
  15.     unsigned char *buf;
  16.  
  17.     if (!PyArg_ParseTuple(args, "slls:lookup",
  18.                 &file_prefix, &file_size, &wc, &word)) {
  19.         return NULL;
  20.     }
  21.     char file_name[256];
  22.     strcpy(file_name, file_prefix);
  23.     strcat(file_name, ".idx");
  24.     if ((fd = open(file_name, O_RDONLY)) <0) {
  25.         printf("open failedn");
  26.         return NULL;
  27.     }
  28.     data = (char *)mmap( NULL, file_size, PROT_READ, MAP_SHARED, fd, 0);
  29.     p = data;
  30.     int i;
  31.     for (i=0;i<wc;i++) {
  32.         index_size = strlen(p) + 1 + 2*sizeof(int);
  33.         if (strcmp(word, p) == 0) {
  34.             flag = 1;
  35.         }
  36.         if (flag == 1) {
  37.             offset = ntohl(*(int *)(p + strlen(p) + 1));
  38.             size   = ntohl(*(int *)(p + strlen(p) + 1 + sizeof(int)));
  39.             //printf("offset=%dnsize%dn",offset,size);
  40.             /*gzFile zfile;
  41.             zfile = gzopen("./dic/stardict-langdao-ec-gb-2.4.2/langdao-ec-gb.dict.dz", "rb");
  42.             gzseek(zfile, offset, SEEK_SET);
  43.             buf = (unsigned char *)malloc(*size+1);
  44.             memset(buf, '', size+1);
  45.             gzread(zfile, buf, size);
  46.             printf("%sn", buf);
  47.             */
  48.             close(fd);
  49.  
  50.             if ((fd = open("./dic/stardict-langdao-ec-gb-2.4.2/langdao-ec-gb.dict", O_RDONLY)) <0) {
  51.                 return NULL;
  52.             }
  53.             lseek(fd, offset, SEEK_SET);
  54.             buf = (unsigned char *)malloc(size+1);
  55.             memset(buf, '', size+1);
  56.             read(fd, buf, size);
  57.             //printf("%sn",buf);
  58.             close(fd);
  59.             return Py_BuildValue("s", buf);
  60.         }
  61.         p += index_size;
  62.     }
  63.  
  64.     return Py_BuildValue("s","");
  65. }
  66.  
  67. static struct PyMethodDef lookup_methods[] = {
  68.     {"lookup", lookup, 1, "lookup(file_prefix, file_size, wc, word)"},
  69.     {NULL, NULL}
  70. };
  71.  
  72. void initlookup()
  73. {
  74.     (void) Py_InitModule("lookup", lookup_methods);
  75. }

使用C语言对进行扩展挺方便的,http://gashero.yeax.com/?p=38#id7这里有个不错的文档。
完了俺整理整理也放在google code上去。

上面的代码中dict文件需要是未gzip压缩过的,如果在压缩过的我使用被注释掉的那段代码在seek的时候速度很慢,又没办法用mmap,所以暂时就先只使用未压缩过的。

标签 :

随机日志

3 楼了已经

  • 草儿写于09年02月26日

    靠,手机看你的博客真费劲

  • okidogi写于09年02月26日

    代码看起来有些晃眼睛...

  • shuge.lee写于09年02月27日

    倒是希望有个Ubiquity+sd for broswer或Lingoes+sd for desktop

发表评论

在下面加入你的评论,或者 trackback 从你的博客站点。 订阅本文的评论。

:

:

:

«
»