Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:10409 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 90192 invoked by uid 1010); 12 Jun 2004 16:32:02 -0000 Delivered-To: ezmlm-scan-internals@lists.php.net Delivered-To: ezmlm-internals@lists.php.net Received: (qmail 90168 invoked by uid 1007); 12 Jun 2004 16:32:02 -0000 To: internals@lists.php.net Date: Sat, 12 Jun 2004 19:31:18 +0300 Organization: none Content-Type: text/plain; format=flowed; delsp=yes; charset=koi8-r MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID: User-Agent: Opera M2/7.50 (Win32, build 3778) X-Posted-By: 217.23.116.150 Subject: crc32() improvements From: valyala@tut.by ("Alexander Valyalkin") Here is improved version of crc32() function. Features: 1) Automatic initialization of crc32tab[] at first call. So, the file crc32.h with definition of this tab is not nessesary any more now. 2) Speed is improved on large amount of data. 3) Less source size. Current verison has near 6.5Kb length (including crc32.h). My version has only 2.5Kb length. Below I provided a test (just copy->compile->test) and unified diff of /ext/standard/crc32.c =============cut============ #include /****************************************************/ /* test data structure */ typedef struct { char *p; /* pointer to a data */ size_t len; /* length of a data */ } my_str; /* set of test data */ my_str s[] = { /* test strings from /ext/standard/tests/strings/crc32.phpt */ {"foo", 3}, {"bar", 3}, {"baz", 3}, {"grldsajkopallkjasd", 18}, /* my test strings */ {"", 0}, /* empty string */ {"\0", 1}, /* one null char */ {"a", 1}, /* one char */ {"ab", 2}, /* two chars */ {"a\0\0b", 4}, /* four chars */ {NULL, 0} }; /****************************************************/ /* faked PHP definitions */ #define PHP_NAMED_FUNCTION(a) void a(char *str1, size_t len1) #define zend_parse_parameters(foo, bar, s1, len) (*(s1) = str1, *(len) = len1, 1) #define TSRMLS_CC #define FAILURE 0 #define RETVAL_LONG(c) do {printf("str=[%s], len=[%d], crc32(unsigned)=[%lu]\n", str1, len1, (c)); return;} while (0) /****************************************************/ /* my crc32 function */ PHP_NAMED_FUNCTION(php_if_crc32) { static unsigned long int crc32tab[256], not_init = 1; if (not_init) { /* init crc32 table */ register unsigned long int tmp, i, j, flag_c; for (i = 0; i < 256; i++) { tmp = i; j = 8; do { if (tmp & 1) { tmp >>= 1; tmp ^= 0xEDB88320; /* CRC32 (CCITT-32) poly g(x) = 1 0000 0100 1100 0001 0001 1101 1011 0111 */ } else tmp >>= 1; j--; } while (j); crc32tab[i] = tmp; } not_init = 0; } /* crc32 calculations */ char *str; int len; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &len) == FAILURE || len < 0) return; if (len == 0) RETVAL_LONG(0); register unsigned long int crc = ~0ul; register unsigned char *p = (unsigned char *) str; register int n = len; do { crc = (crc >> 8) ^ crc32tab[(crc ^ *p++) & 0xff]; n--; } while (n); RETVAL_LONG(~crc); } /***************************************************/ int main(int argc,char *argv[]) { int i = 0; while (s[i].p != NULL) { php_if_crc32(s[i].p, s[i].len); i++; } return 0; } =============cut============ the unified diff of crc32.c: =============cut============ --- crc32.c Tue Dec 31 19:35:26 2002 +++ crc32_new.c Sat Jun 12 19:01:56 2004 @@ -20,24 +20,41 @@ #include "php.h" #include "basic_functions.h" -#include "crc32.h" /* {{{ proto string crc32(string str) Calculate the crc32 polynomial of a string */ PHP_NAMED_FUNCTION(php_if_crc32) { - unsigned int crc = ~0; - char *p; - int len, nr; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &p, &nr) == FAILURE) { - return; + static unsigned long int crc32tab[256], not_init = 1; + if (not_init) { + /* init crc32 table */ + register unsigned long int tmp, i, j, flag_c; + for (i = 0; i < 256; i++) { + tmp = i; + j = 8; + do { + if (tmp & 1) { + tmp >>= 1; + tmp ^= 0xEDB88320; /* CRC32 (CCITT-32) poly g(x) = 1 0000 0100 1100 0001 0001 1101 1011 0111 */ + } else tmp >>= 1; + j--; + } while (j); + crc32tab[i] = tmp; } - - len = 0 ; - for (len += nr; nr--; ++p) { - CRC32(crc, *p); + not_init = 0; } + /* crc32 calculations */ + char *str; + int len; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &len) == FAILURE || len < 0) return; + if (len == 0) RETVAL_LONG(0); + register unsigned long int crc = ~0ul; + register unsigned char *p = (unsigned char *) str; + register int n = len; + do { + crc = (crc >> 8) ^ crc32tab[(crc ^ *p++) & 0xff]; + n--; + } while (n); RETVAL_LONG(~crc); } /* }}} */ =============cut============ -- Using Opera's revolutionary e-mail client: http://www.opera.com/m2/