mirror of
https://github.com/dunglas/frankenphp
synced 2024-11-22 16:19:32 +00:00
feat: improve of performance of PHP variables registration (#94)
* feat: enhance php register variables * apply comments * fix errors * improve benchmark * remove debug statement * use defer * don't use defer in a loop Co-authored-by: Kévin Dunglas <kevin@dunglas.fr>
This commit is contained in:
parent
3abda4fbb6
commit
f0b2eb7445
@ -474,6 +474,14 @@ static char* frankenphp_read_cookies(void)
|
||||
return ctx->cookie_data;
|
||||
}
|
||||
|
||||
void frankenphp_register_bulk_variables(char **variables, size_t size, zval *track_vars_array)
|
||||
{
|
||||
for (size_t i = 0; i < size; i++)
|
||||
{
|
||||
if (i%2 == 1) php_register_variable(variables[i-1], variables[i], track_vars_array);
|
||||
}
|
||||
}
|
||||
|
||||
static void frankenphp_register_variables(zval *track_vars_array)
|
||||
{
|
||||
/* https://www.php.net/manual/en/reserved.variables.server.php */
|
||||
|
@ -444,18 +444,25 @@ func go_register_variables(rh C.uintptr_t, trackVarsArray *C.zval) {
|
||||
r := cgo.Handle(rh).Value().(*http.Request)
|
||||
env = r.Context().Value(contextKey).(*FrankenPHPContext).Env
|
||||
|
||||
// FIXME: remove this debug statement
|
||||
env[fmt.Sprintf("REQUEST_%d", rh)] = "1"
|
||||
le := len(env) * 2
|
||||
cArr := (**C.char)(C.malloc(C.size_t(le) * C.size_t(unsafe.Sizeof((*C.char)(nil)))))
|
||||
defer C.free(unsafe.Pointer(cArr))
|
||||
|
||||
// TODO: batch this for performance
|
||||
variables := unsafe.Slice(cArr, le)
|
||||
|
||||
var i int
|
||||
for k, v := range env {
|
||||
ck := C.CString(k)
|
||||
cv := C.CString(v)
|
||||
variables[i] = C.CString(k)
|
||||
i++
|
||||
|
||||
C.php_register_variable(ck, cv, trackVarsArray)
|
||||
variables[i] = C.CString(v)
|
||||
i++
|
||||
}
|
||||
|
||||
C.free(unsafe.Pointer(ck))
|
||||
C.free(unsafe.Pointer(cv))
|
||||
C.frankenphp_register_bulk_variables(cArr, C.size_t(le), trackVarsArray)
|
||||
|
||||
for _, v := range variables {
|
||||
C.free(unsafe.Pointer(v))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define _FRANKENPPHP_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <Zend/zend_types.h>
|
||||
|
||||
int frankenphp_check_version();
|
||||
int frankenphp_init(int num_threads);
|
||||
@ -26,5 +27,6 @@ uintptr_t frankenphp_clean_server_context();
|
||||
int frankenphp_request_startup();
|
||||
int frankenphp_execute_script(const char *file_name);
|
||||
uintptr_t frankenphp_request_shutdown();
|
||||
void frankenphp_register_bulk_variables(char **variables, size_t size, zval *track_vars_array);
|
||||
|
||||
#endif
|
||||
|
@ -88,6 +88,29 @@ func runTest(t *testing.T, test func(func(http.ResponseWriter, *http.Request), *
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func BenchmarkHelloWorld(b *testing.B) {
|
||||
if err := frankenphp.Init(frankenphp.WithLogger(zap.NewNop())); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer frankenphp.Shutdown()
|
||||
cwd, _ := os.Getwd()
|
||||
testDataDir := cwd + "/testdata/"
|
||||
|
||||
handler := func(w http.ResponseWriter, r *http.Request) {
|
||||
req := frankenphp.NewRequestWithContext(r, testDataDir, nil)
|
||||
if err := frankenphp.ServeHTTP(w, req); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
req := httptest.NewRequest("GET", "http://example.com/index.php", nil)
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
handler(w, req)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHelloWorld_module(t *testing.T) { testHelloWorld(t, nil) }
|
||||
func TestHelloWorld_worker(t *testing.T) { testHelloWorld(t, &testOptions{workerScript: "index.php"}) }
|
||||
func testHelloWorld(t *testing.T, opts *testOptions) {
|
||||
|
Loading…
Reference in New Issue
Block a user