0xDEADBEEF

RSS odkazy english edition

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";
píše k47 (@kaja47, k47)