The documentation doesn't really cover this, so I'm hoping it's OK to ask here.
The FFI docs say that for web requests, you really really ought to use preloading and then load/scope to manage an FFI library because it's going to be too slow to link up otherwise. See the example here:
https://www.php.net/manual/en/ffi.examples-complete.php
What is unclear, though, is the performance impact of calling scope(). It happens at runtime in the example so I presume it's "fast enough" at runtime. However, is it expected that it's only ever called once for a given scope? Or would it be safe to call multiple times in different places just to get an unshared reference to it? Basically, would this be safe or a bad idea, and why?
final class PrintProxy {
private static $ffi = null;
function __construct() {
if (is_null(self::$ffi)) {
self::$ffi = FFI::scope("DUMMY");
}
}
function printf($format, ...$args) {
return (int)self::$ffi->printf($format, ...$args);
}
}
final class SprintfProxy {
private static $ffi = null;
function __construct() {
if (is_null(self::$ffi)) {
self::$ffi = FFI::scope("DUMMY");
}
}
function printf($format, ...$args) {
return (string)self::$ffi->sprintf($format, ...$args);
}
}
The alternative being to have a single object that wraps scope("DUMMY") just once, and then inject that into both of those classes. Is that worth the extra hassle or no, and why?
Thanks to anyone who can help clear this up. (Dmitri? Zeev?)
--
Larry Garfield
larry@garfieldtech.com
The documentation doesn't really cover this, so I'm hoping it's OK to ask here.
The FFI docs say that for web requests, you really really ought to use preloading and then load/scope to manage an FFI library because it's going to be too slow to link up otherwise. See the example here:
https://www.php.net/manual/en/ffi.examples-complete.php
What is unclear, though, is the performance impact of calling scope(). It happens at runtime in the example so I presume it's "fast enough" at runtime. However, is it expected that it's only ever called once for a given scope? Or would it be safe to call multiple times in different places just to get an unshared reference to it? Basically, would this be safe or a bad idea, and why?
final class PrintProxy {
private static $ffi = null;
function __construct() {
if (is_null(self::$ffi)) {
self::$ffi = FFI::scope("DUMMY");
}
}
function printf($format, ...$args) {
return (int)self::$ffi->printf($format, ...$args);
}
}final class SprintfProxy {
private static $ffi = null;
function __construct() {
if (is_null(self::$ffi)) {
self::$ffi = FFI::scope("DUMMY");
}
}
function printf($format, ...$args) {
return (string)self::$ffi->sprintf($format, ...$args);
}
}The alternative being to have a single object that wraps scope("DUMMY") just once, and then inject that into both of those classes. Is that worth the extra hassle or no, and why?
From looking at the implementation[1], FFI::scope() looks like a pretty
cheap operation; basically it's just looking up the scope from a
HashTable, and constructing a thin wrapper object around that.
But as always: when in doubt, measure! :)
[1]
https://github.com/php/php-src/blob/php-7.4.1/ext/ffi/ffi.c#L3387-L3415
--
Christoph M. Becker