-
Notifications
You must be signed in to change notification settings - Fork 61
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Performance: There seems to be a runtime related overhead with using ext-php-rs extensions in PHP #303
Comments
Having similar experience, it seems like converting data from PHP to rust and vice versa is the culprit? |
@bartvanhoutte I'm not entirely sure. I haven't had time to dig through the whole library code so far. |
Yeah data conversion is not the direct culprit here, as no conversion is being done here, most of the library just wraps PHP's zend datastructures. |
Thank you @danog! I just tried running the performance test with gradually increasing the size of the array with random data. Therefore, my conclusion: It might be related to the memory usage somehow. |
@bartvanhoutte that's interesting. Might also be memory related. |
@bgrande Conversion between PHP and Rust types is not free. The structures have to be allocated and the bytes copied. The conversion from Try accepting Zend types as input instead and you should get comparable performance (untested but you get the idea): #[php_function]
pub fn find_mapping(needle: &ZendStr, haystack: &ZendHashTable) -> Option<&ZendStr> {
todo!()
} |
@ju1ius Thank you a lot. That makes a lot of sense. I will try this and report back with the results here. |
Ok, finally an update here: However, I tested @ju1ius suggestions and saw some real improvements here: #[php_function]
pub fn find_mapping(needle: &Zval, haystack: &ZendHashTable) -> Option<String> {
match haystack.iter().position(|elem| elem.1.str() == needle.str()) {
None => None,
Some(_ind) => needle.string()
}
} With that I'm down to avg for a bit more than double the native PHP version. Which is way less than before but still a relatively huge difference. It might work even better with a |
Returning references from Rust functions «exported» to PHP cannot be supported. The Zend Engine is a C API and thus cannot «understand» Rust's generics and lifetimes. Even if it were supported, it would be the wrong thing to do in your case. Whenever you return a reference-counted value from a PHP function, you must increment it's reference count. If your function were implemented in C, it would return a copy of the Also, remember that Zend Strings are just bytes without an encoding. They're conceptually equivalent to a So an even more performant implementation should look like this: #[php_function]
pub fn find_mapping(needle: &Zval, haystack: &ZendHashTable) -> Option<ZVal> {
let Some(needle) = needle.zend_str() else {
return None; // should rather be a type error, but oh well...
};
haystack.iter().find_map(|(_, value)| value.zend_str()
.filter(|zs| zs == needle)
.map(|_| value.shallow_clone())
)
} |
Thx @ju1ius! I haven't thought about the internals much but it makes sense, of course. Your solution is a bit faster, indeed. It went down from a bit more than double to almost double the PHP native functions. I guess, for tasks like this it's probably the best we can do. Apart from my example being a bit constructed we can at least derive a conclusion here, I think: Therefore, this isn't really a bug so closing it would be ok for everyone? |
First of all: Thank you for the great work! It's very interesting and promising.
While testing a simple extension's runtime (measuring time in php script) and running the script multiple times I noticed a constant overhead of around >400ms (at my system) related to my extension build with ext-php-rs.
The comparison for the overhead is a comparable native PHP function and a pure Rust version of it.
Here are the basics:
Rust ext-php-rs
This got built via
cargo build --release
.Rust pure
Also built with
cargo build --release
.PHP with ext-php-rs
using sth. like
/usr/bin/php -d extension=./target/release/librs_php_ext2.so test.php
PHP native
$randomStrings
looks like this:Now, measuring the times with
$start = microtime(true);
and$end = microtime(true)
in the script gives me similar results (depending on the values' position and my machine, of course) like this (for the same string):While Rust pure is quite what you'd expect:
Are there any known issues or did anybody have a similar experience?
The text was updated successfully, but these errors were encountered: