├── .gitignore ├── circle.yml ├── .travis.yml ├── libraries ├── react │ └── package.json ├── vue │ └── package.json ├── svelte │ └── package.json ├── angular │ └── package.json └── ember │ └── package.json ├── README.md ├── LICENSE └── benchmark.sh /.gitignore: -------------------------------------------------------------------------------- 1 | reports*/ 2 | node_modules/ 3 | *.lock 4 | -------------------------------------------------------------------------------- /circle.yml: -------------------------------------------------------------------------------- 1 | machine: 2 | node: 3 | version: 6.8.0 4 | 5 | dependencies: 6 | pre: 7 | - npm install -g yarn 8 | 9 | test: 10 | override: 11 | - ./benchmark.sh 12 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "6" 4 | - "4" 5 | before_install: 6 | - "sudo apt-get install -yqq time" 7 | - "npm install -g yarn" 8 | install: true 9 | script: ./benchmark.sh 10 | -------------------------------------------------------------------------------- /libraries/react/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-demo", 3 | "version": "2.0.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.11.4", 7 | "@testing-library/react": "^11.1.0", 8 | "@testing-library/user-event": "^12.1.10", 9 | "react": "^17.0.2", 10 | "react-dom": "^17.0.2", 11 | "react-scripts": "4.0.3", 12 | "web-vitals": "^1.0.1" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /libraries/vue/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-demo", 3 | "version": "2.0.0", 4 | "private": true, 5 | "dependencies": { 6 | "core-js": "^3.6.5", 7 | "vue": "^3.0.0" 8 | }, 9 | "devDependencies": { 10 | "@vue/cli-plugin-babel": "~4.5.0", 11 | "@vue/cli-plugin-eslint": "~4.5.0", 12 | "@vue/cli-service": "~4.5.0", 13 | "@vue/compiler-sfc": "^3.0.0", 14 | "babel-eslint": "^10.1.0", 15 | "eslint": "^6.7.2", 16 | "eslint-plugin-vue": "^7.0.0" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /libraries/svelte/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "svelte-app", 3 | "version": "2.0.0", 4 | "private": true, 5 | "devDependencies": { 6 | "@rollup/plugin-commonjs": "^17.0.0", 7 | "@rollup/plugin-node-resolve": "^11.0.0", 8 | "rollup": "^2.3.4", 9 | "rollup-plugin-css-only": "^3.1.0", 10 | "rollup-plugin-livereload": "^2.0.0", 11 | "rollup-plugin-svelte": "^7.0.0", 12 | "rollup-plugin-terser": "^7.0.0", 13 | "svelte": "^3.0.0" 14 | }, 15 | "dependencies": { 16 | "sirv-cli": "^1.0.0" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [DEPRECATED] npm-yarn-benchmark 2 | 3 | > 📌 **Deprecation Notice** 4 | > 5 | > This repository is deprecated and no more work will be done on this by [Alberto Varela](https://github.com/artberri). 6 | Bash script for comparing NPM and Yarn performance. 7 | 8 | Any improvement is welcome! 9 | 10 | Create a pull request with your changes or let me know how to improve it by creating an issue. 11 | 12 | ## Run the benchmarking 13 | 14 | ``` 15 | ./benchmark.sh 16 | ``` 17 | 18 | By default it will run twice each installation, use `-n` to change the number of iterations. 19 | 20 | ``` 21 | ./benchmark.sh -n 10 22 | ``` 23 | 24 | The test is run by installing angular2, ember and react N times. Each series is run twice, the 25 | first time cleaning the cache in every run and the second one using the cache. 26 | -------------------------------------------------------------------------------- /libraries/angular/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-demo", 3 | "version": "2.0.0", 4 | "private": true, 5 | "dependencies": { 6 | "@angular/animations": "~12.2.0", 7 | "@angular/common": "~12.2.0", 8 | "@angular/compiler": "~12.2.0", 9 | "@angular/core": "~12.2.0", 10 | "@angular/forms": "~12.2.0", 11 | "@angular/platform-browser": "~12.2.0", 12 | "@angular/platform-browser-dynamic": "~12.2.0", 13 | "@angular/router": "~12.2.0", 14 | "rxjs": "~6.6.0", 15 | "tslib": "^2.3.0", 16 | "zone.js": "~0.11.4" 17 | }, 18 | "devDependencies": { 19 | "@angular-devkit/build-angular": "~12.2.8", 20 | "@angular/cli": "~12.2.8", 21 | "@angular/compiler-cli": "~12.2.0", 22 | "@types/jasmine": "~3.8.0", 23 | "@types/node": "^12.11.1", 24 | "jasmine-core": "~3.8.0", 25 | "karma": "~6.3.0", 26 | "karma-chrome-launcher": "~3.1.0", 27 | "karma-coverage": "~2.0.3", 28 | "karma-jasmine": "~4.0.0", 29 | "karma-jasmine-html-reporter": "~1.7.0", 30 | "typescript": "~4.3.5" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /libraries/ember/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ember-demo", 3 | "version": "2.0.0", 4 | "private": true, 5 | "devDependencies": { 6 | "@ember/optional-features": "^2.0.0", 7 | "@ember/test-helpers": "^2.4.2", 8 | "@glimmer/component": "^1.0.4", 9 | "@glimmer/tracking": "^1.0.4", 10 | "babel-eslint": "^10.1.0", 11 | "broccoli-asset-rev": "^3.0.0", 12 | "ember-auto-import": "^1.11.3", 13 | "ember-cli": "~3.28.0", 14 | "ember-cli-app-version": "^5.0.0", 15 | "ember-cli-babel": "^7.26.6", 16 | "ember-cli-dependency-checker": "^3.2.0", 17 | "ember-cli-htmlbars": "^5.7.1", 18 | "ember-cli-inject-live-reload": "^2.1.0", 19 | "ember-cli-sri": "^2.1.1", 20 | "ember-cli-terser": "^4.0.2", 21 | "ember-data": "~3.28.0", 22 | "ember-export-application-global": "^2.0.1", 23 | "ember-fetch": "^8.1.1", 24 | "ember-load-initializers": "^2.1.2", 25 | "ember-maybe-import-regenerator": "^0.1.6", 26 | "ember-page-title": "^6.2.2", 27 | "ember-qunit": "^5.1.4", 28 | "ember-resolver": "^8.0.2", 29 | "ember-source": "~3.28.0", 30 | "ember-template-lint": "^3.6.0", 31 | "ember-welcome-page": "^4.0.0", 32 | "eslint": "^7.32.0", 33 | "eslint-config-prettier": "^8.3.0", 34 | "eslint-plugin-ember": "^10.5.4", 35 | "eslint-plugin-node": "^11.1.0", 36 | "eslint-plugin-prettier": "^3.4.1", 37 | "eslint-plugin-qunit": "^6.2.0", 38 | "loader.js": "^4.7.0", 39 | "npm-run-all": "^4.1.5", 40 | "prettier": "^2.3.2", 41 | "qunit": "^2.16.0", 42 | "qunit-dom": "^1.6.0" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /benchmark.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Benchmark runner 3 | # Based on https://gist.github.com/peterjmit/3864743 4 | 5 | repeats=3 6 | output_folder='reports' 7 | libraries=('angular' 'ember' 'react' 'vue' 'svelte') 8 | tools=('npm' 'yarn') 9 | base_dir=$PWD 10 | 11 | # Option parsing 12 | while getopts n:o: OPT 13 | do 14 | case "$OPT" in 15 | n) 16 | repeats=$OPTARG 17 | ;; 18 | o) 19 | output_folder=$OPTARG 20 | ;; 21 | \?) 22 | echo 'No arguments supplied' 23 | exit 1 24 | ;; 25 | esac 26 | done 27 | 28 | shift `expr $OPTIND - 1` 29 | 30 | output_folder="${base_dir}/${output_folder}" 31 | 32 | mkdir -p $output_folder 33 | 34 | echo 'Benchmarking: Yarn vs NPM' 35 | echo '========================' 36 | echo 'Running' $repeats 'times per library, test results will be stored in' $output_folder 'directory' 37 | echo '' 38 | 39 | run_tests() { 40 | for tool in "${tools[@]}" 41 | do 42 | avg_file_cc="${output_folder}/avg_${tool}_1.csv" 43 | avg_file="${output_folder}/avg_${tool}_0.csv" 44 | echo -n > $avg_file_cc 45 | echo -n > $avg_file 46 | done 47 | 48 | for library in "${libraries[@]}" 49 | do 50 | echo $library '=>'; 51 | for tool in "${tools[@]}" 52 | do 53 | run_benchmark $tool 1 $library # Cleaning cache 54 | run_benchmark $tool 0 $library # Without cleaning cache 55 | done 56 | done 57 | } 58 | 59 | run_benchmark() { 60 | tool=$1 61 | clean_cache=$2 62 | library=$3 63 | directory="${base_dir}/libraries/${library}" 64 | output_file="${output_folder}/${tool}_${clean_cache}_${library}.csv" 65 | avg_file="${output_folder}/avg_${tool}_${clean_cache}.csv" 66 | 67 | echo -n > $output_file 68 | 69 | case "$tool" in 70 | yarn) 71 | command_to_run='yarn install' 72 | command_to_clear_cache='yarn cache clean' 73 | ;; 74 | npm) 75 | command_to_run='npm install --cache-min 999999' 76 | command_to_clear_cache='npm cache clean' 77 | ;; 78 | *) 79 | exit 1 80 | ;; 81 | esac 82 | 83 | cd $directory 84 | 85 | if [ $clean_cache = 1 ]; then 86 | cache_text='with clean cache' 87 | else 88 | cache_text='' 89 | 90 | # Install once to generate cache 91 | rm -rf node_modules 92 | rm -f yarn.lock 93 | $command_to_run > /dev/null 2>&1 94 | fi 95 | 96 | echo ' '${tool} ${cache_text} 97 | 98 | # Run the given command [repeats] times 99 | for (( i = 1; i <= $repeats ; i++ )) 100 | do 101 | rm -rf node_modules 102 | rm -f yarn.lock 103 | 104 | # Clean cache 105 | if [ $clean_cache = 1 ]; then 106 | $command_to_clear_cache > /dev/null 2>&1 107 | fi 108 | 109 | # runs time function for the called script, output in a comma seperated 110 | # format output file specified with -o command and -a specifies append 111 | /usr/bin/time -f "%e %U %S" -o ${output_file} -a ${command_to_run} > /dev/null 2>&1 112 | 113 | # percentage completion 114 | p=$(( $i * 100 / $repeats)) 115 | # indicator of progress 116 | l=$(seq -s "+" $i | sed 's/[0-9]//g') 117 | 118 | echo -ne ' '${l}' ('${p}'%) \r' 119 | done; 120 | 121 | echo -ne '\n' 122 | 123 | avg=$(awk '{ total += $1; count++ } END { print total/count }' $output_file) 124 | echo -n $avg' ' >> $avg_file 125 | 126 | cd $base_dir 127 | } 128 | 129 | show_results() { 130 | all_file=${output_folder}/avg.csv 131 | echo -n > $all_file 132 | 133 | for tool in "${tools[@]}" 134 | do 135 | avg_file_cc="${output_folder}/avg_${tool}_1.csv" 136 | avg_file="${output_folder}/avg_${tool}_0.csv" 137 | 138 | echo -n $tool'_with_empty_cache ' >> $all_file 139 | cat $avg_file_cc >> $all_file 140 | echo >> $all_file 141 | echo -n $tool'_with_all_cached ' >> $all_file 142 | cat $avg_file >> $all_file 143 | echo >> $all_file 144 | done 145 | 146 | echo '' 147 | echo ' ----------------------------------------------------------------------------------------------------- ' 148 | echo ' ----------------------------------------- RESULTS (seconds) ----------------------------------------- ' 149 | echo ' ----------------------------------------------------------------------------------------------------- ' 150 | 151 | awk 'BEGIN {printf("| %24s | %12s | %12s | %12s | %12s | %12s | \n" , " ", "'${libraries[0]}'", "'${libraries[1]}'", "'${libraries[2]}'", "'${libraries[3]}'", "'${libraries[4]}'")} 152 | {printf("| %24s | %12.3f | %12.3f | %12.3f | %12.3f | %12.3f | \n", $1, $2, $3, $4, $5, $6)}' $all_file 153 | 154 | echo ' ----------------------------------------------------------------------------------------------------- ' 155 | } 156 | 157 | run_tests 158 | show_results 159 | 160 | echo $npm 161 | --------------------------------------------------------------------------------