PHP の uniqid 関数
の実行が遅いという問題 少し前の要件: すべての端末 (PC、パッド、電話) に適したスクラッチ カード アクティビティ用の H5 ページを作成するための簡単なフォームを顧客が送信し、それを生成する必要があります。オンライン機能では賞品コードの数に6Wの制限があります。
各イベントの賞品コードを一意に保つ必要があるため、最初に PHP の uniqid 関数を使用して UUID (Universally Unique IDentifier、GUID とも呼ばれ、アルゴリズムによって生成されるグローバルに一意な識別子) を生成する準備をします。 )を生成します。
しかし、テストのために 1W を生成していたとき、データベースに挿入する時間を除いて、生成に数十秒かかることがわかりました。そこで、パフォーマンス テスト用に xhprof を使用した簡単な例を作成しました。
<?phpxhprof_enable(XHPROF_FLAGS_CPU|XHPROF_FLAGS_MEMORY);function myfunc(){ for($i=0;$i<10000;$i++){ $data = uniqid(); }}myfunc();$data = xhprof_disable();print_r($data);
[myfunc==>uniqid] => Array( [ct] => 10000 [wt] => 39975062 [cpu] => 0 [mu] => 960752 [pmu] => 0)
PHP_FUNCTION(uniqid){ char *prefix = "";#if defined(__CYGWIN__) zend_bool more_entropy = 1;#else zend_bool more_entropy = 0;#endif char *uniqid; int sec, usec, prefix_len = 0; struct timeval tv; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sb", &prefix, &prefix_len, &more_entropy)) { return; }#if HAVE_USLEEP && !defined(PHP_WIN32) if (!more_entropy) {#if defined(__CYGWIN__) php_error_docref(NULL TSRMLS_CC, E_WARNING, "You must use 'more entropy' under CYGWIN"); RETURN_FALSE;#else usleep(1);#endif }#endif gettimeofday((struct timeval *) &tv, (struct timezone *) NULL); sec = (int) tv.tv_sec; usec = (int) (tv.tv_usec % 0x100000); /* The max value usec can have is 0xF423F, so we use only five hex * digits for usecs. */ if (more_entropy) { spprintf(&uniqid, 0, "%s%08x%05x%.8F", prefix, sec, usec, php_combined_lcg(TSRMLS_C) * 10); } else { spprintf(&uniqid, 0, "%s%08x%05x", prefix, sec, usec); } RETURN_STRING(uniqid, 0);}
int getUniqid( char * uid) { int sec, usec; struct timeval tv; gettimeofday(( struct timeval *) &tv, ( struct timezone *) NULL); sec = ( int) tv. tv_sec; usec = ( int ) (tv.tv_usec % 0x100000); sprintf(uid, "%08x%05x" , sec, usec); return 1;}
struct timeval start, end; gettimeofday(( struct timeval *) &start, ( struct timezone *) NULL); usleep(1); gettimeofday(( struct timeval *) &end, ( struct timezone *) NULL); unsigned long space = (end.tv_sec - start. tv_sec) * 1000000 + end.tv_usec - start. tv_usec; spaceCost += space;