From 4a2e4ff112af13eb318a63783dc109e2eab5e9f2 Mon Sep 17 00:00:00 2001 From: Matias De lellis Date: Tue, 14 Apr 2020 09:45:16 -0300 Subject: [PATCH 1/3] Implement dlib_vector_length to calculate the euclidean distance of the vectors It not use the 'length' native versions of dlib, due I have to convert the array to the vector, which will take the same time, and then I will use the native method. --- config.m4 | 14 +++++++----- pdlib.cc | 5 ++++- php_pdlib.h | 2 +- src/vector.cc | 47 ++++++++++++++++++++++++++++++++++++++++ src/vector.h | 10 +++++++++ tests/vector_length.phpt | 14 ++++++++++++ tests/version.phpt | 10 +++++++++ 7 files changed, 94 insertions(+), 8 deletions(-) create mode 100644 src/vector.cc create mode 100644 src/vector.h create mode 100644 tests/vector_length.phpt create mode 100644 tests/version.phpt diff --git a/config.m4 b/config.m4 index 7e990f3..3cf7534 100644 --- a/config.m4 +++ b/config.m4 @@ -24,12 +24,14 @@ if test "$PHP_PDLIB" != "no"; then PHP_ADD_LIBRARY(stdc++, 1, PDLIB_SHARED_LIBADD) PHP_SUBST(PDLIB_SHARED_LIBADD) - pdlib_src_files="pdlib.cc \ - src/chinese_whispers.cc \ - src/face_detection.cc \ - src/face_landmark_detection.cc \ - src/face_recognition.cc \ - src/cnn_face_detection.cc " + pdlib_src_files=" + pdlib.cc \ + src/chinese_whispers.cc \ + src/face_detection.cc \ + src/face_landmark_detection.cc \ + src/face_recognition.cc \ + src/cnn_face_detection.cc \ + src/vector.cc" AC_MSG_CHECKING(for pkg-config) if test ! -f "$PKG_CONFIG"; then diff --git a/pdlib.cc b/pdlib.cc index 76bf514..f848407 100644 --- a/pdlib.cc +++ b/pdlib.cc @@ -27,12 +27,14 @@ extern "C" { #include "php_ini.h" #include "ext/standard/info.h" } + #include "php_pdlib.h" #include "src/chinese_whispers.h" #include "src/face_detection.h" #include "src/face_recognition.h" #include "src/cnn_face_detection.h" #include "src/face_landmark_detection.h" +#include "src/vector.h" /* If you declare any globals in php_pdlib.h uncomment this: ZEND_DECLARE_MODULE_GLOBALS(pdlib) @@ -260,10 +262,11 @@ PHP_MINFO_FUNCTION(pdlib) * Every user visible function must have an entry in pdlib_functions[]. */ const zend_function_entry pdlib_functions[] = { - PHP_FE(confirm_pdlib_compiled, NULL) + PHP_FE(confirm_pdlib_compiled, NULL) PHP_FE(dlib_chinese_whispers, dlib_chinese_whispers_arginfo) PHP_FE(dlib_face_detection, dlib_face_detection_arginfo) PHP_FE(dlib_face_landmark_detection, dlib_face_landmark_detection_arginfo) + PHP_FE(dlib_vector_length, dlib_vector_length_arginfo) PHP_FE_END /* Must be the last line in pdlib_functions[] */ }; /* }}} */ diff --git a/php_pdlib.h b/php_pdlib.h index ab29c2e..5e61714 100644 --- a/php_pdlib.h +++ b/php_pdlib.h @@ -31,7 +31,7 @@ extern "C" { extern zend_module_entry pdlib_module_entry; #define phpext_pdlib_ptr &pdlib_module_entry -#define PHP_PDLIB_VERSION "1.0.1" /* Replace with version number for your extension */ +#define PHP_PDLIB_VERSION "1.0.2" /* Replace with version number for your extension */ #ifdef PHP_WIN32 # define PHP_PDLIB_API __declspec(dllexport) diff --git a/src/vector.cc b/src/vector.cc new file mode 100644 index 0000000..7a590fb --- /dev/null +++ b/src/vector.cc @@ -0,0 +1,47 @@ + +#include "../php_pdlib.h" + +#include "vector.h" + +#include +#include +#include + +using namespace std; + +PHP_FUNCTION(dlib_vector_length) +{ + zval *x_arg, *y_arg; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "aa", &x_arg, &y_arg) == FAILURE) { + zend_throw_exception_ex( + zend_ce_exception, + 0 TSRMLS_CC, + "Unable to parse arrays in dlib_vector_length"); + return; + } + + zval *elem_x, *elem_y; + double sum = 0.0; + int i, len; + + len = zend_hash_num_elements(Z_ARRVAL_P(x_arg)); + + if (len != zend_hash_num_elements(Z_ARRVAL_P(y_arg))) { + zend_throw_exception_ex( + zend_ce_exception, + 0 TSRMLS_CC, + "The arrays have different sizes"); + return; + } + + for (i = 0 ; i < len ; i++) { + elem_x = zend_hash_index_find(Z_ARRVAL_P(x_arg), i); + elem_y = zend_hash_index_find(Z_ARRVAL_P(y_arg), i); + + sum += pow(Z_DVAL_P(elem_x) - Z_DVAL_P(elem_y), 2); + } + + RETURN_DOUBLE(sqrt(sum)); +} + diff --git a/src/vector.h b/src/vector.h new file mode 100644 index 0000000..d8dd8c6 --- /dev/null +++ b/src/vector.h @@ -0,0 +1,10 @@ +#ifndef PHP_DLIB_VECTOR_H +#define PHP_DLIB_VECTOR_H + +ZEND_BEGIN_ARG_INFO_EX(dlib_vector_length_arginfo, 0, 0, 2) + ZEND_ARG_INFO(0, x_arg) + ZEND_ARG_INFO(0, y_arg) +ZEND_END_ARG_INFO() +PHP_FUNCTION(dlib_vector_length); + +#endif //PHP_DLIB_VECTOR_H diff --git a/tests/vector_length.phpt b/tests/vector_length.phpt new file mode 100644 index 0000000..c840d49 --- /dev/null +++ b/tests/vector_length.phpt @@ -0,0 +1,14 @@ +--TEST-- +Basic tests for dlib_vector_length +--SKIPIF-- + +--FILE-- + +--EXPECT-- +float(1) +float(2) +float(1.5) \ No newline at end of file diff --git a/tests/version.phpt b/tests/version.phpt new file mode 100644 index 0000000..21a891e --- /dev/null +++ b/tests/version.phpt @@ -0,0 +1,10 @@ +--TEST-- +Just test php extension version +--SKIPIF-- + +--FILE-- + +--EXPECT-- +string(5) "1.0.2" \ No newline at end of file From 75adc6f80162f7167b615e11e46e727453f9e9c2 Mon Sep 17 00:00:00 2001 From: Matias De lellis Date: Tue, 14 Apr 2020 10:26:26 -0300 Subject: [PATCH 2/3] Use references as an attempt to optimize. --- src/vector.h | 4 ++-- tests/vector_length.phpt | 12 +++++++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/vector.h b/src/vector.h index d8dd8c6..536b0f3 100644 --- a/src/vector.h +++ b/src/vector.h @@ -2,8 +2,8 @@ #define PHP_DLIB_VECTOR_H ZEND_BEGIN_ARG_INFO_EX(dlib_vector_length_arginfo, 0, 0, 2) - ZEND_ARG_INFO(0, x_arg) - ZEND_ARG_INFO(0, y_arg) + ZEND_ARG_INFO(1, x_arg) + ZEND_ARG_INFO(1, y_arg) ZEND_END_ARG_INFO() PHP_FUNCTION(dlib_vector_length); diff --git a/tests/vector_length.phpt b/tests/vector_length.phpt index c840d49..60b4747 100644 --- a/tests/vector_length.phpt +++ b/tests/vector_length.phpt @@ -4,9 +4,15 @@ Basic tests for dlib_vector_length --FILE-- --EXPECT-- float(1) From 76da4d9b843c44e3e7a037eb75249e94fa706a23 Mon Sep 17 00:00:00 2001 From: Matias De lellis Date: Tue, 14 Apr 2020 10:45:13 -0300 Subject: [PATCH 3/3] Multiply directly instead of using pow ($number, 2); This small optimization allows us to improve from: OLD php: 0.012100038051605 Sec. New native: 0.0096198790073395 Sec. (This is already 20 percent faster) ..to: OLD php: 0.012276937961578 Sec. New native: 0.0022540950775146 Sec. What is 80 percent faster than our PHP class. --- src/vector.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vector.cc b/src/vector.cc index 7a590fb..460d916 100644 --- a/src/vector.cc +++ b/src/vector.cc @@ -39,7 +39,7 @@ PHP_FUNCTION(dlib_vector_length) elem_x = zend_hash_index_find(Z_ARRVAL_P(x_arg), i); elem_y = zend_hash_index_find(Z_ARRVAL_P(y_arg), i); - sum += pow(Z_DVAL_P(elem_x) - Z_DVAL_P(elem_y), 2); + sum += (Z_DVAL_P(elem_x) - Z_DVAL_P(elem_y))*(Z_DVAL_P(elem_x) - Z_DVAL_P(elem_y)); } RETURN_DOUBLE(sqrt(sum));