PHP FFI
28. 9. 2021 #kód
const ITERS = 10000; const SIZE = 1024; $arr = range(0, SIZE); $splArr = new SplFixedArray(SIZE); $ffiArr = \FFI::new("uint32_t[".SIZE."]"); $str = pack('V*', ...range(0, SIZE)); $sink = 0; $s = hrtime(1); for ($it = 0; $it < ITERS; $it++) { for ($i = 0; $i < SIZE; $i++) { $sink += $i; } } echo "nil ", (hrtime(1)-$s) / SIZE / ITERS, "\n"; $s = hrtime(1); for ($it = 0; $it < ITERS; $it++) { for ($i = 0; $i < SIZE; $i++) { $sink += $arr[$i]; } } echo "arr ", (hrtime(1)-$s) / SIZE / ITERS, "\n"; $s = hrtime(1); for ($it = 0; $it < ITERS; $it++) { for ($i = 0; $i < SIZE; $i++) { $sink += $splArr[$i]; } } echo "spl ", (hrtime(1)-$s) / SIZE / ITERS, "\n"; $s = hrtime(1); for ($it = 0; $it < ITERS; $it++) { for ($i = 0; $i < SIZE; $i++) { $sink += $ffiArr[$i]; } } echo "ffi ", (hrtime(1)-$s) / SIZE / ITERS, "\n"; $s = hrtime(1); for ($it = 0; $it < ITERS; $it++) { for ($i = 0; $i < SIZE; $i++) { $sink += unpack('V', $str, $i * 4)[1]; } } echo "pack ", (hrtime(1)-$s) / SIZE / ITERS, "\n"; $s = hrtime(1); for ($it = 0; $it < ITERS; $it++) { for ($i = 0; $i < SIZE; $i += 32) { $tmp = unpack('V32', $str, $i * 4); for ($j = 0; $j < 32; $j++) { $sink += $tmp[$j + 1]; } } } echo "pack32 ", (hrtime(1)-$s) / SIZE / ITERS, "\n"; $s = hrtime(1); for ($it = 0; $it < ITERS; $it++) { for ($i = 0; $i < SIZE; $i++) { $pos = $i * 4; $sink += ord($str[$pos]) | (ord($str[$pos+1]) << 8) | (ord($str[$pos+2]) << 16) | (ord($str[$pos+3]) << 24); } } echo "ord ", (hrtime(1)-$s) / SIZE / ITERS, "\n"; echo "\n(", $sink, ")\n\n";
const ITERS = 10000; const SIZE = 1024; $str = str_repeat("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b", SIZE); $sink = 0; const PATTERN = 'Vid/vnum/Cx/Clen/a20rest'; $s = hrtime(1); $item = unpack(PATTERN, $str); for ($it = 0; $it < ITERS; $it++) { for ($i = 0; $i < SIZE; $i++) { $sink += $item['id'] ^ $item['num'] ^ $item['x'] ^ $item['len'] ^ strlen($item['rest']); } } echo "nil ", (hrtime(1)-$s) / SIZE / ITERS, "\n"; $s = hrtime(1); for ($it = 0; $it < ITERS; $it++) { for ($i = 0; $i < SIZE; $i++) { $item = unpack(PATTERN, $str, $i * 28); $sink += $item['id'] ^ $item['num'] ^ $item['x'] ^ $item['len'] ^ strlen($item['rest']); } } echo "pack ", (hrtime(1)-$s) / SIZE / ITERS, "\n"; $ffi = FFI::cdef("struct __attribute__ ((packed)) Item { uint32_t id; uint16_t num; uint8_t x; uint8_t len; char rest[20]; };"); $charArrType = FFI::arrayType(FFI::type("char"), [strlen($str)]); $s = hrtime(1); for ($it = 0; $it < ITERS; $it++) { $chars = $ffi->new($charArrType); FFI::memcpy($chars, $str, strlen($str)); $items = $ffi->cast('struct Item*', $chars); for ($i = 0; $i < SIZE; $i++) { $item = $items[$i]; $rest = FFI::string($item->rest, 20); $sink += $item->id ^ $item->num ^ $item->x ^ $item->len ^ strlen($rest); } } echo "ffi ", (hrtime(1)-$s) / SIZE / ITERS, "\n"; echo "\n(", $sink, ")\n";