2019-10-25 20:19:49 0 Comments Go Boy.Lee

Go vs PHP CLI Performance Compare Under Special Project Environment

I am planing a movie recommendation project recently. One of the core parts is to recommend interested movies through user behavior. Considering the large amount of calculation, I want to find a more "fast" language, because we use the command line mode, so fast is enough. My first goal is Go. I made this "interesting" Go Vs PHP Cli test and the results can be completely different from what I imagined, so I sorted out all data for your reference.

 

{ No.1 Basic Info }

Scenario: App recommending interested movies to the user. This test mainly considers the implementation of the recommendation algorithm.

Process: User select condition by App, writes in Recommend Task Queue(to DB)via RESTful API, then run algorithm in command line and save result back to DB, at the end feedback user the result by API in App

Data: the amount of movie data is in 100,000 class, and the associated data is complex: Category, Language, Region, Starring, Director, Writer etc

 

{ No.2 Testing Envorinment }

  1. one MBP Pro(I am in the vacation ⛱️ now, only have this one in hand, ^^), CPU 2.3GHz, Memery 16GB
  2. Go v1.13 without framework, direct use packs(github.com/go-sql-driver/mysql etc)
  3. php v5.6.24 and v7.1, use Yii 2.0 framework
  4. Database MySQL v5.7.15,  this test doesn't consider the impact of database

 

{ No.3 Testing Plan }

The recommended logic mainly loops through the following two types of operations:

  1. Loading data from database, more than 90% database operations are reading
  2. Analyze and calculate the loaded data

The ratio of database operations and data analysis is approximately 7:3. So I conceived the following test samples:

Generate a random number in given range, use it as PK to query location table once, use one loaded field(int type) to add with the random number (fake some loop and condition operations, in the meantime), after all done, send the sum number to next round, then random load and sum, run 1000, 5000 and 50000 rounds to check the time cost(All tests were averaged 10 times to reduce the deviation)

 

{ No.4 Single Thread Mode }

First is Single Thread Mode. It is my favorite mode, because some interference factors are removed, the benchmark can be built better. In the subsequent tests, more complex modes will be considered, but this mode is still an important reference standard.

Lang 1000 times 5000 times 50000 times
Go 0.1451s 0.7075s 7.0355s
PHP5 CLI 0.2519s 1.4001s 14.3123s
PHP7 CLI 0.1061s 0.4939s 4.9861s


Points: 

  1. All PHP run with Yii2.0's DAO mode, no AR mode here, AR is a little slow and Go use DAO mode too
  2. All test results are got average from 10 times same tests, to reduce the deviation, same for all tests in the topic

 

The test results made me very surprised. To be honest, I was thinking PHP7 CLI mode should be close to the PHP5 CLI mode in the table. Go should be faster, but actually PHP7 is 50% faster than Go.Maybe the test plan is not fair to Go, but it's all based on my requirements.

 

{ No.5 PHP5 CLI vs Web }

This is an add on test, after all tests finished, I was thinking how many different between PHP Web and CLI mode. So I ran this test under PHP5

Mode 1000 times 5000 times 10000 times
PHP5 CLI 0.2519s 1.4001s 2.6424s
PHP5 Web 0.3940s 1.9377s 4.6751s

 

Points:

  1. There is max memery limit for web mode so I cut the max round from 50000 to 10000

The same code Web is lower than the CLI, about 50% difference, which is completely as expected.

 

{ No.6 PHP7 CLI DAO vs AR }

in Yii 2.0 framework there are two type database operate modes: DAO(Data Access Object use SQL operate DB) and AR(Active Record use ORM model operate DB), AR is slower than DAO because have one more layer of data model and some relaed operations. But AR also brings some ex-functions and faster in Dev, so the significante here is balance the efficiency between Development and Operational.

Mode 1000 times 5000 times 50000 times
PHP7 CLI AR 0.1643s 0.7092s 7.1816s
PHP7 CLI DAO 0.1061s 0.4939s 4.9861s

Through the data, AR costs 40% performance then DAO, and this is only in the single scenario of reading, and it will be more complex in actual projects. But to be honest, I am willing to use 40% of the performance in exchange for the convenience brought by AR, the development convenience that AR can bring is very large, can not list all here. There are two tips that using DAO in important versions and complex scenarios is a must, and it is very beneficial to use AR in the early versions of development (MVP) and non-critical versions.

 

{ No.7 Multi-Threaded Parallel Test }

In the actual production scenario, for Go or PHP CLI, we will switch to multi-threaded parallel mode to run, so I designed the following testing scenario:

  1. Go Multi-Threaded Parallel Testing, use "go" keyword to open goroutines
  2. PHP Multi-Threaded Parallel Testing, my plan is open some windows in iTerm2 and run same command in all windows(equal to manual multi-threading), the code will output start and end time, just need find the earliest start time and the lastest end time, the difference is the totally run time.
  3. The two type Multi-Threaded tests are diff, but it's enough for me, I am curious how the results will be.
  4. At the end, I added Manual Multi-Thread test for Go in iTerm2

 

Mode 1000 *5 times 5000*5 times 50000*5 times
Go with goroutines 0.2801s 1.4198s 14.5827s
Go with 5 iterm sessions 0.3211s 1.4439s 14.0207s
PHP7 CLI with 5 iterm sessions 0.192s 0.9562s 9.4134s

 Points:

  1. in gorountines testing I was trying to add runtime.GOMAXPROCS, my plan was use it to max the parallel efficency for Go, but it's not change any thing. I am thinking that the defualt max processes is big enough.
  2. in gorountines testing, I also tryed runtime.Gosched, nothing change neither.
  3. I made the above changes to get Go to achieve the best parallel efficieny, but I don't have enough Go experience so I am not sure I made it in the best way, I will fix it if I found any error.

Sure enough, PHP7's CLI mode performs better, with almost 40% performance advantage (if use AR mode, it will increase the performance consumption by 40%, then equal to the Go effect)

 

{ No.8 Concultion }

Honestly, the final test results made me very surprised. At the beginning of the test, I thought that Go DAO would be 30%-40% faster than PHP7 CLI DAO. But the results are PHP7 CLI DAO is faster than Go DAO 40%, PHP7 CLI AR is equal to Go DAO. At the same time, PHP is using Yii 2.0 framwork, I guess the raw PHP will faster, but I didn't plan to build code with Raw PHP, so I didn't test it.

In the end, I selected PHP7 CLI DAO mode to build the v1.0 for my App(will use PHP7 CLI AR for early versions), I am very familir with this mode in last years, so it will save a lot times for me.

Here again, it's not a full cover test, it's only suit for my Project only! So it's not enough to say which one is better in PHP7 and Go, just PHP7 is better for my project that's all. I will spend more time on Go Study in next steps, because it's really amazing, It's already on my list.

 

{ No.9 Not Cover List }

The Following items will be cover in next tests:

  1. CPU usage
  2. Memery usage
  3. The bottleneck of multi-threaded parallel testing

 

{ No.10 Next Plan }

After v1.0 done, I will do one more regression testing, I had a feeling that some are missing in this test, but I don't have enough time to thinking deep(it's my vacation time... ^^), so I made a next test plan here. ok to be continues.... 

 

{ Ref. } 

All Test Code