What does C ++ output look like for the HipHop PHP compiler?

Is it enough enough that you can give up PHP and optimize C ++ code manually?

+4
source share
2 answers

The short answer is no .

Since I spent some time getting HipHop to work, I decided to share my results here so that I didn’t feel like a WASTE of time.

Here is my PHP input:

  & lt?

 class test {
  function loop () {
   for ($ i = 0; $ i <10; ++ $ i) {
     echo ("i = $ i \ n");
   }
  }
 }

 $ t = new test ();
 $ t-> loop ();

 ?>

And here is the C ++ output ...

 #include <php / hello.h> #include <cpp / ext / ext.h> namespace HPHP {/////////////////////////// //////////////////////////////////////////////////// // / * preface starts * / / * preface finishes * / / * SRC: hello.php line 3 * / Variant c_test :: os_get (const char * s, int64 hash) {return c_ObjectData :: os_get (s, hash) ;  } Variant & c_test :: os_lval (const char * s, int64 hash) {return c_ObjectData :: os_lval (s, hash);  } void c_test :: o_get (ArrayElementVec & props) const {c_ObjectData :: o_get (props);  } bool c_test :: o_exists (CStrRef s, int64 hash) const {return c_ObjectData :: o_exists (s, hash);  } Variant c_test :: o_get (CStrRef s, int64 hash) {return c_ObjectData :: o_get (s, hash);  } Variant c_test :: o_set (CStrRef s, int64 hash, CVarRef v, bool forInit / * = false * /) {return c_ObjectData :: o_set (s, hash, v, forInit);  } Variant & c_test :: o_lval (CStrRef s, int64 hash) {return c_ObjectData :: o_lval (s, hash);  } Variant c_test :: os_constant (const char * s) {return c_ObjectData :: os_constant (s);  } IMPLEMENT_CLASS (test) ObjectData * c_test :: cloneImpl () {c_test * obj = NEW (c_test) ();  cloneSet (obj);  return obj;  } void c_test :: cloneSet (c_test * clone) {ObjectData :: cloneSet (clone);  } Variant c_test :: o_invoke (const char * s, CArrRef params, int64 hash, bool fatal) {if (hash <0) hash = hash_string_i (s);  switch (hash & 1) {case 1: HASH_GUARD (0x0EA59CD1566F5709LL, loop) {return (t_loop (), null);  } break;  default: break;  } return c_ObjectData :: o_invoke (s, params, hash, fatal);  } Variant c_test :: o_invoke_few_args (const char * s, int64 hash, int count, CVarRef a0, CVarRef a1, CVarRef a2, CVarRef a3, CVarR ef a4, CVarRef a5) {if (hash <0) hash = hash_string_i (s ;  switch (hash & 1) {case 1: HASH_GUARD (0x0EA59CD1566F5709LL, loop) {return (t_loop (), null);  } break;  default: break;  } return c_ObjectData :: o_invoke_few_args (s, hash, count, a0, a1, a2, a3, a4, a5);  } Variant c_test :: os_invoke (const char * c, const char * s, CArrRef params, int64 hash, bool fatal) {return c_ObjectData :: os_invoke (c, s, params, hash, fatal);  } Variant cw_test $ os_get (const char * s) {return c_test :: os_get (s, -1);  } Variant & cw_test $ os_lval (const char * s) {return c_test :: os_lval (s, -1);  } Variant cw_test $ os_constant (const char * s) {return c_test :: os_constant (s);  } Variant cw_test $ os_invoke (const char * c, const char * s, CArrRef params, bool fatal / * = true * /) {return c_test :: os_invoke (c, s, params, -1, fatal);  } void c_test :: init () {} / * SRC: hello.php line 4 * / void c_test :: t_loop () {INSTANCE_METHOD_INJECTION (test, test :: loop);  int64 v_i = 0;  {LOOP_COUNTER (1);  for ((v_i = 0LL); less (v_i, 10LL); ++ v_i) {LOOP_COUNTER_CHECK (1);  {echo ((LINE (6, concat3 ("i =", toString (v_i), "\ n"))));  }}}} / * function * / Object co_test (CArrRef params, bool init / * = true * /) {return Object (p_test (NEW (c_test) ()) -> dynCreate (params, init));  } Variant pm_php $ hello_php (bool incOnce / * = false * /, LVariableTable * variables / * = NULL * /) {FUNCTION_INJECTION (run_init :: hello.php);  {DECLARE_GLOBAL_VARIABLES (g);  bool & alreadyRun = g-> run_pm_php $ hello_php;  if (alreadyRun) {if (incOnce) return true;} else alreadyRun = true;  if (! variables) variables = g;  } DECLARE_GLOBAL_VARIABLES (g);  LVariableTable * gVariables __attribute __ ((__ unused__)) = get_variable_table ();  Variant & v_t __attribute __ ((__ unused__)) = (variables! = GVariables)?  variables-> get ("t"): g-> GV (t);  (v_t = ((Object) (LINE (11, p_test (p_test (NEWOBJ (c_test) ()) -> create ())))));  LINE (12, v_t.o_invoke_few_args ("loop", 0x0EA59CD1566F5709LL, 0));  return true;  } / * function * / //////////////////////////////////////////// ///////////////////////////////////} 

Ugh! It took me a few seconds to find the loop ...

+7
source

β†’ "A C ++ programmer, written from scratch, would write the same thing with almost the same code size than your PHP snippet (using STL).

A G-WAN ANSI C script programmer, written from scratch, would write (much more efficient) code below:

static inline void loop(xbuf_t *reply) { int i = 0; while(i < 10) xbuf_xcat(reply, "i = %d\n", i++); } int main(int argc, char *argv[]) { xbuf_t *reply = get_reply(argv); loop(reply); return 200; } 

The curious will evaluate each implementation. really curious will check the memory usage.

Even Lighttpd or Nginx with pre-compiled C ++ is slower than G-WAN C scripts.

Food for thought...

0
source

Source: https://habr.com/ru/post/1306525/


All Articles