- Add GitHub/GitHut pull requests and pushes.
- Add StackOverflow tag counts (this also involves some hard-coded
rollup of certain tags).
- Add README with update instructions.
- Move graph specific data mangling from collect code to graph
rendering code.
--- /dev/null
+# Mal Implementation Stats Graph
+
+
+## Updating the data
+
+* Install prerequisites:
+
+```
+sudo aptitude install ruby2.3-dev
+sudo gem install travis --no-rdoc --no-ri
+```
+
+* Download the latest successful travis build (BUILD is the travis
+ build number):
+
+```
+cd docs/graph
+
+BUILD=983
+
+for x in $(seq 1 90); do echo ${BUILD}/${x}; mkdir -p logs/${BUILD}; while ! travis logs ${BUILD}.${x} > logs/${BUILD}/${x}; do true; done; done
+```
+
+* Run the [StackOverflow tags query](https://data.stackexchange.com/stackoverflow/query/edit/1013465) and update the CSV link:
+
+```
+export SO_TAG_CSV_URL=... # from the query page
+```
+
+```
+
+* Download GitHub and StackOverflow data and generate the final
+ combined data set:
+
+```
+PATH=$PATH:~/personal/programming/loccount
+
+time VERBOSE=1 node ./collect_data.js logs/${BUILD}/ all_data.json
+```
"perf1": 9,
"perf2": 28,
"perf3": 1089,
- "star_count": null,
- "rank": 68,
+ "pull_count": 221,
+ "pull_rank": 58,
+ "push_count": 18891,
+ "push_rank": 54,
+ "star_count": 213,
+ "star_rank": 60,
"sloc": 5942,
"files": 29,
"author_name": "Chris Moore",
"author_url": "https://github.com/zmower",
+ "so_count": 1620,
+ "so_rank": 50,
"lloc": 3759
},
"awk": {
"perf1": 14,
"perf2": 47,
"perf3": 702,
- "star_count": 355,
- "rank": 50,
+ "pull_count": null,
+ "pull_rank": null,
+ "push_count": 4052,
+ "push_rank": 60,
+ "star_count": 5775,
+ "star_rank": 49,
"sloc": 5213,
"files": 17,
"author_name": "Miutsuru Kariya",
"author_url": "https://github.com/kariya-mitsuru",
+ "so_count": 23834,
+ "so_rank": 23,
"lloc": 0
},
"bash": {
"perf1": 1681,
"perf2": 7748,
"perf3": 5,
- "star_count": 59906,
- "rank": 14,
+ "pull_count": 492673,
+ "pull_rank": 12,
+ "push_count": 4076842,
+ "push_rank": 10,
+ "star_count": 1314476,
+ "star_rank": 14,
"sloc": 2392,
"files": 18,
"author_name": "Joel Martin",
"author_url": "https://github.com/kanaka",
+ "so_count": 109843,
+ "so_rank": 14,
"lloc": 0
},
"basic": {
"perf1": 11,
"perf2": 49,
"perf3": 871,
+ "pull_count": null,
+ "pull_rank": null,
+ "push_count": null,
+ "push_rank": null,
"star_count": null,
- "rank": 68,
+ "star_rank": null,
"sloc": 3963,
"files": 23,
"author_name": "Joel Martin",
"author_url": "https://github.com/kanaka",
+ "so_count": 673,
+ "so_rank": 54,
"lloc": 3956
},
"c": {
"syntax": "C",
"type_check": "Static",
"modes": [],
- "perf1": 0.9,
+ "perf1": 0,
"perf2": 2,
"perf3": 17211,
- "star_count": 90804,
- "rank": 9,
+ "pull_count": 827476,
+ "pull_rank": 9,
+ "push_count": 5526508,
+ "push_rank": 8,
+ "star_count": 2273480,
+ "star_rank": 10,
"sloc": 3701,
"files": 26,
"author_name": "Joel Martin",
"author_url": "https://github.com/kanaka",
+ "so_count": 299022,
+ "so_rank": 7,
"lloc": 2012
},
"cpp": {
"syntax": "C",
"type_check": "Static",
"modes": [],
- "perf1": 0.9,
+ "perf1": 0,
"perf2": 1,
"perf3": 16045,
- "star_count": 139366,
- "rank": 6,
+ "pull_count": 1356841,
+ "pull_rank": 7,
+ "push_count": 8102807,
+ "push_rank": 6,
+ "star_count": 2690455,
+ "star_rank": 9,
"sloc": 3532,
"files": 29,
"author_name": "Stephen Thirlwall",
"author_url": "https://github.com/sdt",
+ "so_count": 666534,
+ "so_rank": 6,
"lloc": 1617
},
"cs": {
"perf1": 9,
"perf2": 10,
"perf3": 14958,
- "star_count": 76670,
- "rank": 10,
+ "pull_count": 756538,
+ "pull_rank": 10,
+ "push_count": 4833303,
+ "push_rank": 9,
+ "star_count": 1311416,
+ "star_rank": 15,
"sloc": 3396,
"files": 20,
"author_name": "Joel Martin",
"author_url": "https://github.com/kanaka",
+ "so_count": 1325942,
+ "so_rank": 4,
"lloc": 1760
},
"chuck": {
"perf1": 35,
"perf2": 113,
"perf3": 132,
+ "pull_count": null,
+ "pull_rank": null,
+ "push_count": null,
+ "push_rank": null,
"star_count": null,
- "rank": 68,
+ "star_rank": null,
"sloc": 4962,
"files": 98,
"author_name": "Vasilij Schneidermann",
"author_url": "https://github.com/wasamasa",
+ "so_count": 19,
+ "so_rank": 71,
"lloc": 1796
},
"clojure": {
"perf1": 25,
"perf2": 66,
"perf3": 2373,
- "star_count": 5502,
- "rank": 27,
+ "pull_count": 88279,
+ "pull_rank": 23,
+ "push_count": 482086,
+ "push_rank": 23,
+ "star_count": 228280,
+ "star_rank": 22,
"sloc": 1207,
"files": 23,
"author_name": "Joel Martin",
"author_url": "https://github.com/kanaka",
+ "so_count": 15387,
+ "so_rank": 29,
"lloc": 0
},
"coffee": {
"perf1": 7,
"perf2": 33,
"perf3": 18111,
- "star_count": 8569,
- "rank": 22,
+ "pull_count": 179032,
+ "pull_rank": 19,
+ "push_count": 686417,
+ "push_rank": 20,
+ "star_count": 512339,
+ "star_rank": 17,
"sloc": 1073,
"files": 21,
"author_name": "Joel Martin",
"author_url": "https://github.com/kanaka",
+ "so_count": 9675,
+ "so_rank": 35,
"lloc": 0
},
"common-lisp": {
"perf1": 1,
"perf2": 2,
"perf3": 14665,
- "star_count": 1146,
- "rank": 38,
+ "pull_count": 7509,
+ "pull_rank": 45,
+ "push_count": 89833,
+ "push_rank": 40,
+ "star_count": 31757,
+ "star_rank": 36,
"sloc": 2607,
"files": 22,
"author_name": "Iqbal Ansari",
"author_url": "https://github.com/iqbalansari",
+ "so_count": 4719,
+ "so_rank": 43,
"lloc": 0
},
"crystal": {
"perf1": 1,
"perf2": 2,
"perf3": 28255,
- "star_count": 938,
- "rank": 41,
+ "pull_count": 7228,
+ "pull_rank": 47,
+ "push_count": 25868,
+ "push_rank": 51,
+ "star_count": 19192,
+ "star_rank": 44,
"sloc": 2157,
"files": 18,
"author_name": "Linda_pp",
"author_url": "https://github.com/rhysd",
+ "so_count": 456,
+ "so_rank": 56,
"lloc": 0
},
"d": {
"syntax": "C",
"type_check": "Static",
"modes": [],
- "perf1": 0.9,
+ "perf1": 0,
"perf2": 2,
"perf3": 15621,
- "star_count": 653,
- "rank": 45,
+ "pull_count": 7432,
+ "pull_rank": 46,
+ "push_count": 67755,
+ "push_rank": 44,
+ "star_count": 15362,
+ "star_rank": 45,
"sloc": 2979,
"files": 18,
"author_name": "Dov Murik",
"author_url": "https://github.com/dubek",
+ "so_count": 2453,
+ "so_rank": 49,
"lloc": 1434
},
"dart": {
"perf1": 14,
"perf2": 38,
"perf3": 509,
- "star_count": 2498,
- "rank": 34,
+ "pull_count": 36851,
+ "pull_rank": 34,
+ "push_count": 132610,
+ "push_rank": 35,
+ "star_count": 31684,
+ "star_rank": 37,
"sloc": 2279,
"files": 18,
"author_name": "Harry Terkelsen",
"author_url": "https://github.com/hterkelsen",
+ "so_count": 14514,
+ "so_rank": 32,
"lloc": 1142
},
"elixir": {
"perf1": 14,
"perf2": 52,
"perf3": 765,
- "star_count": 6115,
- "rank": 24,
+ "pull_count": 57336,
+ "pull_rank": 27,
+ "push_count": 168462,
+ "push_rank": 34,
+ "star_count": 133408,
+ "star_rank": 24,
"sloc": 1824,
"files": 20,
"author_name": "Martin Ek",
"author_url": "https://github.com/ekmartin",
+ "so_count": 6737,
+ "so_rank": 38,
"lloc": 0
},
"elm": {
"perf1": 69,
"perf2": 167,
"perf3": 801,
- "star_count": 809,
- "rank": 43,
+ "pull_count": 10763,
+ "pull_rank": 41,
+ "push_count": 51061,
+ "push_rank": 46,
+ "star_count": 29708,
+ "star_rank": 40,
"sloc": 5775,
"files": 24,
"author_name": "Jos van Bakel",
"author_url": "https://github.com/c0deaddict",
+ "so_count": 1469,
+ "so_rank": 51,
"lloc": 0
},
"elisp": {
"perf1": 16,
"perf2": 77,
"perf3": 593,
- "star_count": 5689,
- "rank": 26,
+ "pull_count": 45932,
+ "pull_rank": 32,
+ "push_count": 288975,
+ "push_rank": 26,
+ "star_count": 111705,
+ "star_rank": 27,
"sloc": 1982,
"files": 20,
"author_name": "Vasilij Schneidermann",
"author_url": "https://github.com/wasamasa",
+ "so_count": 3661,
+ "so_rank": 46,
"lloc": 0
},
"erlang": {
"perf1": 53,
"perf2": 175,
"perf3": 175,
- "star_count": 2942,
- "rank": 31,
+ "pull_count": 62128,
+ "pull_rank": 25,
+ "push_count": 242256,
+ "push_rank": 29,
+ "star_count": 114897,
+ "star_rank": 26,
"sloc": 2215,
"files": 18,
"author_name": "Nathan Fiedler",
"author_url": "https://github.com/nlfiedler",
+ "so_count": 8426,
+ "so_rank": 37,
"lloc": 0
},
"es6": {
"perf1": 3,
"perf2": 21,
"perf3": 12079,
- "star_count": 668062,
- "rank": 2,
+ "pull_count": 5493469,
+ "pull_rank": 2,
+ "push_count": 22904060,
+ "push_rank": 2,
+ "star_count": 17647699,
+ "star_rank": 2,
"sloc": 1230,
"files": 20,
"author_name": "Joel Martin",
"author_url": "https://github.com/kanaka",
+ "so_count": 153997,
+ "so_rank": 12,
"lloc": 0
},
"fsharp": {
"perf1": 35,
"perf2": 29,
"perf3": 20634,
- "star_count": 950,
- "rank": 39,
+ "pull_count": 25939,
+ "pull_rank": 36,
+ "push_count": 125060,
+ "push_rank": 36,
+ "star_count": 29958,
+ "star_rank": 39,
"sloc": 3033,
"files": 22,
"author_name": "Peter Stephens",
"author_url": "https://github.com/pstephens",
+ "so_count": 14506,
+ "so_rank": 33,
"lloc": 404
},
"factor": {
"perf1": 2,
"perf2": 1,
"perf3": 27766,
- "star_count": null,
- "rank": 68,
+ "pull_count": null,
+ "pull_rank": null,
+ "push_count": 11230,
+ "push_rank": 57,
+ "star_count": 100,
+ "star_rank": 62,
"sloc": 1305,
"files": 33,
"author_name": "Jordan Lewis",
"author_url": "https://github.com/jordanlewis",
+ "so_count": 61,
+ "so_rank": 66,
"lloc": 0
},
"fantom": {
"perf1": 14,
"perf2": 31,
"perf3": 40400,
+ "pull_count": null,
+ "pull_rank": null,
+ "push_count": null,
+ "push_rank": null,
"star_count": null,
- "rank": 68,
+ "star_rank": null,
"sloc": 1768,
"files": 31,
"author_name": "Dov Murik",
"author_url": "https://github.com/dubek",
+ "so_count": 54,
+ "so_rank": 67,
"lloc": 0
},
"forth": {
"perf1": 4,
"perf2": 14,
"perf3": 2448,
- "star_count": null,
- "rank": 68,
+ "pull_count": null,
+ "pull_rank": null,
+ "push_count": 7173,
+ "push_rank": 59,
+ "star_count": 106,
+ "star_rank": 61,
"sloc": 3351,
"files": 21,
"author_name": "Chris Houser",
"author_url": "https://github.com/chouser",
+ "so_count": 210,
+ "so_rank": 60,
"lloc": 0
},
"guile": {
"perf1": 3,
"perf2": 9,
"perf3": 3962,
+ "pull_count": null,
+ "pull_rank": null,
+ "push_count": null,
+ "push_rank": null,
"star_count": null,
- "rank": 68,
+ "star_rank": null,
"sloc": 1547,
"files": 20,
"author_name": "Mu Lei",
"author_url": "https://github.com/NalaGinrut",
+ "so_count": 186,
+ "so_rank": 61,
"lloc": 0
},
"gnu-smalltalk": {
"perf1": 14,
"perf2": 45,
"perf3": 787,
- "star_count": 152,
- "rank": 55,
+ "pull_count": 9786,
+ "pull_rank": 42,
+ "push_count": 39964,
+ "push_rank": 47,
+ "star_count": 1697,
+ "star_rank": 56,
"sloc": 2444,
"files": 21,
"author_name": "Vasilij Schneidermann",
"author_url": "https://github.com/wasamasa",
+ "so_count": 86,
+ "so_rank": 63,
"lloc": 0
},
"go": {
"perf1": 1,
"perf2": 3,
"perf3": 10334,
- "star_count": 215511,
- "rank": 5,
+ "pull_count": 1211699,
+ "pull_rank": 8,
+ "push_count": 3354592,
+ "push_rank": 11,
+ "star_count": 3635813,
+ "star_rank": 5,
"sloc": 3451,
"files": 20,
"author_name": "Joel Martin",
"author_url": "https://github.com/kanaka",
+ "so_count": 36753,
+ "so_rank": 22,
"lloc": 1792
},
"groovy": {
"perf1": 477,
"perf2": 746,
"perf3": 324,
- "star_count": 4302,
- "rank": 29,
+ "pull_count": 78505,
+ "pull_rank": 24,
+ "push_count": 330188,
+ "push_rank": 25,
+ "star_count": 99463,
+ "star_rank": 29,
"sloc": 1598,
"files": 19,
"author_name": "Joel Martin",
"author_url": "https://github.com/kanaka",
+ "so_count": 22656,
+ "so_rank": 24,
"lloc": 0
},
"haskell": {
"perf1": 3,
"perf2": 8,
"perf3": 4338,
- "star_count": 6312,
- "rank": 23,
+ "pull_count": 105004,
+ "pull_rank": 21,
+ "push_count": 772035,
+ "push_rank": 18,
+ "star_count": 244427,
+ "star_rank": 20,
"sloc": 2011,
"files": 18,
"author_name": "Joel Martin",
"author_url": "https://github.com/kanaka",
+ "so_count": 40268,
+ "so_rank": 21,
"lloc": 0
},
"haxe": {
"perf1": 5,
"perf2": 26,
"perf3": 15377,
- "star_count": 580,
- "rank": 46,
+ "pull_count": 12391,
+ "pull_rank": 40,
+ "push_count": 68980,
+ "push_rank": 43,
+ "star_count": 24119,
+ "star_rank": 41,
"sloc": 2270,
"files": 23,
"author_name": "Joel Martin",
"author_url": "https://github.com/kanaka",
+ "so_count": 1400,
+ "so_rank": 52,
"lloc": 1045
},
"hy": {
"perf1": 17,
"perf2": 67,
"perf3": 585,
- "star_count": null,
- "rank": 68,
+ "pull_count": 108,
+ "pull_rank": 59,
+ "push_count": 1442,
+ "push_rank": 62,
+ "star_count": 308,
+ "star_rank": 59,
"sloc": 1215,
"files": 18,
"author_name": "Joel Martin",
"author_url": "https://github.com/kanaka",
+ "so_count": 29,
+ "so_rank": 70,
"lloc": 0
},
"io": {
"perf1": 357,
"perf2": 1333,
"perf3": 29,
+ "pull_count": null,
+ "pull_rank": null,
+ "push_count": 224,
+ "push_rank": 64,
"star_count": null,
- "rank": 68,
+ "star_rank": null,
"sloc": 1262,
"files": 18,
"author_name": "Dov Murik",
"author_url": "https://github.com/dubek",
+ "so_count": 14548,
+ "so_rank": 31,
"lloc": 0
},
"java": {
"perf1": 7,
"perf2": 24,
"perf3": 57275,
- "star_count": 255160,
- "rank": 4,
+ "pull_count": 2390505,
+ "pull_rank": 4,
+ "push_count": 12425871,
+ "push_rank": 4,
+ "star_count": 6191792,
+ "star_rank": 4,
"sloc": 3061,
"files": 20,
"author_name": "Joel Martin",
"author_url": "https://github.com/kanaka",
+ "so_count": 1527471,
+ "so_rank": 2,
"lloc": 1537
},
"js": {
"perf1": 3,
"perf2": 22,
"perf3": 14550,
- "star_count": 668062,
- "rank": 1,
- "sloc": 2779,
- "files": 33,
+ "pull_count": 5493469,
+ "pull_rank": 1,
+ "push_count": 22904060,
+ "push_rank": 1,
+ "star_count": 17647699,
+ "star_rank": 1,
+ "sloc": 1986,
+ "files": 26,
"author_name": "Joel Martin",
"author_url": "https://github.com/kanaka",
+ "so_count": 3154942,
+ "so_rank": 1,
"lloc": 0
},
"julia": {
"perf1": 253,
"perf2": 32,
"perf3": 2975,
- "star_count": 948,
- "rank": 40,
+ "pull_count": 46318,
+ "pull_rank": 31,
+ "push_count": 201339,
+ "push_rank": 33,
+ "star_count": 37036,
+ "star_rank": 35,
"sloc": 1413,
"files": 19,
"author_name": "Joel Martin",
"author_url": "https://github.com/kanaka",
+ "so_count": 5134,
+ "so_rank": 42,
"lloc": 0
},
"kotlin": {
"perf1": 19,
"perf2": 75,
"perf3": 33381,
- "star_count": 20958,
- "rank": 17,
+ "pull_count": 55156,
+ "pull_rank": 29,
+ "push_count": 229722,
+ "push_rank": 30,
+ "star_count": 167915,
+ "star_rank": 23,
"sloc": 1571,
"files": 19,
"author_name": "Javier Fernandez-Ivern",
"author_url": "https://github.com/ivern",
+ "so_count": 20934,
+ "so_rank": 25,
"lloc": 0
},
"livescript": {
"perf1": 6,
"perf2": 26,
"perf3": 7570,
- "star_count": 116,
- "rank": 57,
+ "pull_count": 238,
+ "pull_rank": 57,
+ "push_count": 14525,
+ "push_rank": 56,
+ "star_count": 8475,
+ "star_rank": 48,
"sloc": 2128,
"files": 19,
"author_name": "Jos van Bakel",
"author_url": "https://github.com/c0deaddict",
+ "so_count": 66,
+ "so_rank": 64,
"lloc": 0
},
"logo": {
"modes": [],
"perf1": 19182,
"perf2": 53948,
- "perf3": 0.01,
+ "perf3": 0,
+ "pull_count": null,
+ "pull_rank": null,
+ "push_count": null,
+ "push_rank": null,
"star_count": null,
- "rank": 68,
+ "star_rank": null,
"sloc": 2139,
"files": 20,
"author_name": "Dov Murik",
"author_url": "https://github.com/dubek",
+ "so_count": 43,
+ "so_rank": 68,
"lloc": 0
},
"lua": {
"perf1": 10,
"perf2": 44,
"perf3": 955,
- "star_count": 8769,
- "rank": 21,
+ "pull_count": 98464,
+ "pull_rank": 22,
+ "push_count": 597735,
+ "push_rank": 22,
+ "star_count": 241491,
+ "star_rank": 21,
"sloc": 1909,
"files": 21,
"author_name": "Joel Martin",
"author_url": "https://github.com/kanaka",
+ "so_count": 15214,
+ "so_rank": 30,
"lloc": 0
},
"make": {
"perf1": 5050,
"perf2": 31077,
"perf3": 1,
- "star_count": 2034,
- "rank": 35,
+ "pull_count": 60803,
+ "pull_rank": 26,
+ "push_count": 251529,
+ "push_rank": 27,
+ "star_count": 57750,
+ "star_rank": 32,
"sloc": 1821,
"files": 22,
"author_name": "Joel Martin",
"author_url": "https://github.com/kanaka",
+ "so_count": 18769,
+ "so_rank": 27,
"lloc": 0
},
"mal": {
"perf1": 277,
"perf2": 1346,
"perf3": 40,
+ "pull_count": null,
+ "pull_rank": null,
+ "push_count": null,
+ "push_rank": null,
"star_count": null,
- "rank": 68,
+ "star_rank": null,
"sloc": 890,
"files": 13,
"author_name": "Joel Martin",
"author_url": "https://github.com/kanaka",
+ "so_count": 0,
+ "so_rank": 73,
"lloc": 0
},
"matlab": {
"perf1": 1709,
"perf2": 6295,
"perf3": 5,
- "star_count": 2867,
- "rank": 32,
+ "pull_count": 20935,
+ "pull_rank": 37,
+ "push_count": 264,
+ "push_rank": 63,
+ "star_count": 46295,
+ "star_rank": 34,
"sloc": 2204,
"files": 27,
"author_name": "Joel Martin",
"author_url": "https://github.com/kanaka",
+ "so_count": 82801,
+ "so_rank": 16,
"lloc": 0
},
"miniMAL": {
"perf1": 1340,
"perf2": 5383,
"perf3": 7,
+ "pull_count": null,
+ "pull_rank": null,
+ "push_count": null,
+ "push_rank": null,
"star_count": null,
- "rank": 68,
+ "star_rank": null,
"sloc": 1691,
"files": 20,
"author_name": "Joel Martin",
"author_url": "https://github.com/kanaka",
+ "so_count": 0,
+ "so_rank": 74,
"lloc": 0
},
"nasm": {
"syntax": "OTHER",
"type_check": "OTHER",
"modes": [],
- "perf1": 0.9,
+ "perf1": 0,
"perf2": 2,
"perf3": 24147,
- "star_count": 1195,
- "rank": 37,
+ "pull_count": 9679,
+ "pull_rank": 43,
+ "push_count": 91017,
+ "push_rank": 39,
+ "star_count": 31339,
+ "star_rank": 38,
"sloc": 14483,
"files": 19,
"author_name": "Ben Dudson",
"author_url": "https://github.com/bendudson",
+ "so_count": 3420,
+ "so_rank": 47,
"lloc": 0
},
"nim": {
"perf1": 1,
"perf2": 2,
"perf3": 30900,
- "star_count": 529,
- "rank": 48,
+ "pull_count": 1674,
+ "pull_rank": 54,
+ "push_count": 7741,
+ "push_rank": 58,
+ "star_count": 4783,
+ "star_rank": 52,
"sloc": 1423,
"files": 17,
"author_name": "Dennis Felsing",
"author_url": "https://github.com/def-",
+ "so_count": 289,
+ "so_rank": 58,
"lloc": 0
},
"objpascal": {
"perf1": 4,
"perf2": 12,
"perf3": 2830,
- "star_count": 1324,
- "rank": 36,
+ "pull_count": 5360,
+ "pull_rank": 48,
+ "push_count": 72591,
+ "push_rank": 42,
+ "star_count": 20971,
+ "star_rank": 43,
"sloc": 6179,
"files": 20,
"author_name": "Joel Martin",
"author_url": "https://github.com/kanaka",
+ "so_count": 57574,
+ "so_rank": 20,
"lloc": 3971
},
"objc": {
"perf1": 6,
"perf2": 28,
"perf3": 1599,
- "star_count": 48248,
- "rank": 16,
+ "pull_count": 263283,
+ "pull_rank": 14,
+ "push_count": 1310542,
+ "push_rank": 13,
+ "star_count": 3020863,
+ "star_rank": 6,
"sloc": 2363,
"files": 26,
"author_name": "Joel Martin",
"author_url": "https://github.com/kanaka",
+ "so_count": 287020,
+ "so_rank": 8,
"lloc": 1059
},
"ocaml": {
"perf1": 1,
"perf2": 2,
"perf3": 23267,
- "star_count": 3646,
- "rank": 30,
+ "pull_count": 56046,
+ "pull_rank": 28,
+ "push_count": 227050,
+ "push_rank": 31,
+ "star_count": 87278,
+ "star_rank": 31,
"sloc": 1269,
"files": 17,
"author_name": "Chris Houser",
"author_url": "https://github.com/chouser",
+ "so_count": 5633,
+ "so_rank": 41,
"lloc": 0
},
"perl": {
"perf1": 13,
"perf2": 50,
"perf3": 790,
- "star_count": 4679,
- "rank": 28,
+ "pull_count": 115736,
+ "pull_rank": 20,
+ "push_count": 628215,
+ "push_rank": 21,
+ "star_count": 119328,
+ "star_rank": 25,
"sloc": 2265,
"files": 22,
"author_name": "Joel Martin",
"author_url": "https://github.com/kanaka",
+ "so_count": 61960,
+ "so_rank": 19,
"lloc": 1107
},
"perl6": {
"perf1": 441,
"perf2": 1182,
"perf3": 23,
- "star_count": 137,
- "rank": 56,
+ "pull_count": 2624,
+ "pull_rank": 52,
+ "push_count": 14541,
+ "push_rank": 55,
+ "star_count": 846,
+ "star_rank": 58,
"sloc": 1238,
"files": 18,
"author_name": "Hinrik Örn Sigurðsson",
"author_url": "https://github.com/hinrik",
+ "so_count": 1018,
+ "so_rank": 53,
"lloc": 484
},
"php": {
"perf1": 8,
"perf2": 28,
"perf3": 1268,
- "star_count": 135579,
- "rank": 7,
+ "pull_count": 1895495,
+ "pull_rank": 6,
+ "push_count": 9066974,
+ "push_rank": 5,
+ "star_count": 2789804,
+ "star_rank": 8,
"sloc": 1998,
"files": 21,
"author_name": "Joel Martin",
"author_url": "https://github.com/kanaka",
+ "so_count": 1270824,
+ "so_rank": 5,
"lloc": 1074
},
"picolisp": {
"perf1": 2,
"perf2": 7,
"perf3": 6005,
+ "pull_count": null,
+ "pull_rank": null,
+ "push_count": null,
+ "push_rank": null,
"star_count": null,
- "rank": 68,
+ "star_rank": null,
"sloc": 1366,
"files": 20,
"author_name": "Vasilij Schneidermann",
"author_url": "https://github.com/wasamasa",
+ "so_count": 5,
+ "so_rank": 72,
"lloc": 0
},
"plpgsql": {
"perf1": 478,
"perf2": 3830,
"perf3": 20,
- "star_count": 897,
- "rank": 42,
+ "pull_count": 16628,
+ "pull_rank": 38,
+ "push_count": 85763,
+ "push_rank": 41,
+ "star_count": 14707,
+ "star_rank": 46,
"sloc": 3679,
"files": 21,
"author_name": "Joel Martin",
"author_url": "https://github.com/kanaka",
+ "so_count": 2788,
+ "so_rank": 48,
"lloc": 0
},
"plsql": {
"syntax": "Algol",
"type_check": "Static",
"modes": [],
- "perf1": 19182,
- "perf2": 1921,
- "perf3": 0.01,
- "star_count": 199,
- "rank": 53,
+ "perf1": null,
+ "perf2": null,
+ "perf3": 0,
+ "pull_count": 9421,
+ "pull_rank": 44,
+ "push_count": 31400,
+ "push_rank": 48,
+ "star_count": 3983,
+ "star_rank": 54,
"sloc": 4180,
"files": 21,
"author_name": "Joel Martin",
"author_url": "https://github.com/kanaka",
+ "so_count": 20149,
+ "so_rank": 26,
"lloc": 0
},
"powershell": {
"perf1": 1921,
"perf2": 7832,
"perf3": 5,
- "star_count": 5795,
- "rank": 25,
+ "pull_count": 52513,
+ "pull_rank": 30,
+ "push_count": 217208,
+ "push_rank": 32,
+ "star_count": 90595,
+ "star_rank": 30,
"sloc": 1147,
"files": 12,
"author_name": "Joel Martin",
"author_url": "https://github.com/kanaka",
+ "so_count": 66407,
+ "so_rank": 18,
"lloc": 0
},
"ps": {
"perf1": 38,
"perf2": 274,
"perf3": 198,
- "star_count": null,
- "rank": 68,
+ "pull_count": 1644,
+ "pull_rank": 55,
+ "push_count": 19145,
+ "push_rank": 53,
+ "star_count": 1034,
+ "star_rank": 57,
"sloc": 2482,
"files": 20,
"author_name": "Joel Martin",
"author_url": "https://github.com/kanaka",
+ "so_count": 458,
+ "so_rank": 55,
"lloc": 0
},
"python": {
"perf1": 7,
"perf2": 29,
"perf3": 1371,
- "star_count": 336045,
- "rank": 3,
+ "pull_count": 3673660,
+ "pull_rank": 3,
+ "push_count": 15034581,
+ "push_rank": 3,
+ "star_count": 6487808,
+ "star_rank": 3,
"sloc": 1358,
"files": 20,
"author_name": "Joel Martin",
"author_url": "https://github.com/kanaka",
+ "so_count": 1374530,
+ "so_rank": 3,
"lloc": 1344
},
"rpython": {
"syntax": "Python",
"type_check": "Static",
"modes": [],
- "perf1": 0.9,
+ "perf1": 0,
"perf2": 1,
"perf3": 69848,
+ "pull_count": null,
+ "pull_rank": null,
+ "push_count": null,
+ "push_rank": null,
"star_count": null,
- "rank": 68,
+ "star_rank": null,
"sloc": 2102,
"files": 19,
"author_name": "Joel Martin",
"author_url": "https://github.com/kanaka",
+ "so_count": 64,
+ "so_rank": 65,
"lloc": 2096
},
"r": {
"perf1": 78,
"perf2": 295,
"perf3": 117,
- "star_count": 2644,
- "rank": 33,
+ "pull_count": 40953,
+ "pull_rank": 33,
+ "push_count": 455945,
+ "push_rank": 24,
+ "star_count": 55128,
+ "star_rank": 33,
"sloc": 1625,
"files": 19,
"author_name": "Joel Martin",
"author_url": "https://github.com/kanaka",
+ "so_count": 281400,
+ "so_rank": 9,
"lloc": 0
},
"racket": {
"perf1": 2,
"perf2": 7,
"perf3": 4865,
- "star_count": 281,
- "rank": 51,
+ "pull_count": 3167,
+ "pull_rank": 51,
+ "push_count": 28005,
+ "push_rank": 50,
+ "star_count": 5573,
+ "star_rank": 50,
"sloc": 1193,
"files": 18,
"author_name": "Joel Martin",
"author_url": "https://github.com/kanaka",
+ "so_count": 4344,
+ "so_rank": 45,
"lloc": 0
},
"rexx": {
"perf1": 160,
"perf2": 660,
"perf3": 61,
+ "pull_count": null,
+ "pull_rank": null,
+ "push_count": null,
+ "push_rank": null,
"star_count": null,
- "rank": 68,
+ "star_rank": null,
"sloc": 2747,
"files": 19,
"author_name": "Dov Murik",
"author_url": "https://github.com/dubek",
+ "so_count": 125,
+ "so_rank": 62,
"lloc": 0
},
"ruby": {
"perf1": 2,
"perf2": 8,
"perf3": 4163,
- "star_count": 54043,
- "rank": 15,
+ "pull_count": 2079423,
+ "pull_rank": 5,
+ "push_count": 5952146,
+ "push_rank": 7,
+ "star_count": 2821992,
+ "star_rank": 7,
"sloc": 1291,
"files": 20,
"author_name": "Joel Martin",
"author_url": "https://github.com/kanaka",
+ "so_count": 203216,
+ "so_rank": 11,
"lloc": 0
},
"rust": {
"syntax": "C",
"type_check": "Static",
"modes": [],
- "perf1": 0.9,
+ "perf1": 0,
"perf2": 1,
"perf3": 16720,
- "star_count": 19178,
- "rank": 18,
+ "pull_count": 197385,
+ "pull_rank": 18,
+ "push_count": 710977,
+ "push_rank": 19,
+ "star_count": 396731,
+ "star_rank": 19,
"sloc": 2862,
"files": 18,
"author_name": "Joel Martin",
"author_url": "https://github.com/kanaka",
+ "so_count": 11560,
+ "so_rank": 34,
"lloc": 714
},
"scala": {
"perf1": 27,
"perf2": 66,
"perf3": 25785,
- "star_count": 13634,
- "rank": 19,
+ "pull_count": 316175,
+ "pull_rank": 13,
+ "push_count": 1104784,
+ "push_rank": 14,
+ "star_count": 419380,
+ "star_rank": 18,
"sloc": 1849,
"files": 18,
"author_name": "Joel Martin",
"author_url": "https://github.com/kanaka",
+ "so_count": 87665,
+ "so_rank": 15,
"lloc": 0
},
"scheme": {
"perf1": 6,
"perf2": 19,
"perf3": 2231,
- "star_count": 718,
- "rank": 44,
+ "pull_count": 3528,
+ "pull_rank": 49,
+ "push_count": 63905,
+ "push_rank": 45,
+ "star_count": 21437,
+ "star_rank": 42,
"sloc": 1269,
"files": 13,
"author_name": "Vasilij Schneidermann",
"author_url": "https://github.com/wasamasa",
+ "so_count": 6678,
+ "so_rank": 39,
"lloc": 0
},
"skew": {
"perf1": 6,
"perf2": 11,
"perf3": 3608,
+ "pull_count": null,
+ "pull_rank": null,
+ "push_count": null,
+ "push_rank": null,
"star_count": null,
- "rank": 68,
+ "star_rank": null,
"sloc": 1638,
"files": 19,
"author_name": "Dov Murik",
"author_url": "https://github.com/dubek",
+ "so_count": 263,
+ "so_rank": 59,
"lloc": 0
},
"swift": {
"perf1": 2,
"perf2": 6,
"perf3": 5322,
- "star_count": 66012,
- "rank": 11,
+ "pull_count": 231080,
+ "pull_rank": 15,
+ "push_count": 931308,
+ "push_rank": 15,
+ "star_count": 1992397,
+ "star_rank": 11,
"sloc": 2963,
"files": 14,
"author_name": "Keith Rollin",
"author_url": "https://github.com/keith-rollin",
+ "so_count": 8527,
+ "so_rank": 36,
"lloc": 0
},
"swift3": {
"perf1": 8,
"perf2": 27,
"perf3": 1234,
- "star_count": 66012,
- "rank": 12,
+ "pull_count": 231080,
+ "pull_rank": 16,
+ "push_count": 931308,
+ "push_rank": 16,
+ "star_count": 1992397,
+ "star_rank": 12,
"sloc": 2362,
"files": 17,
"author_name": "Joel Martin",
"author_url": "https://github.com/kanaka",
+ "so_count": 18339,
+ "so_rank": 28,
"lloc": 0
},
"swift4": {
"perf1": 5,
"perf2": 16,
"perf3": 2065,
- "star_count": 66012,
- "rank": 13,
+ "pull_count": 231080,
+ "pull_rank": 17,
+ "push_count": 931308,
+ "push_rank": 17,
+ "star_count": 1992397,
+ "star_rank": 13,
"sloc": 1767,
"files": 17,
"author_name": "陆遥",
"author_url": "https://github.com/LispLY",
+ "so_count": 230173,
+ "so_rank": 10,
"lloc": 0
},
"tcl": {
"perf1": 24,
"perf2": 103,
"perf3": 373,
- "star_count": 171,
- "rank": 54,
+ "pull_count": 3399,
+ "pull_rank": 50,
+ "push_count": 28306,
+ "push_rank": 49,
+ "star_count": 3111,
+ "star_rank": 55,
"sloc": 2468,
"files": 20,
"author_name": "Dov Murik",
"author_url": "https://github.com/dubek",
+ "so_count": 6056,
+ "so_rank": 40,
"lloc": 0
},
"ts": {
"perf1": 4,
"perf2": 14,
"perf3": 26534,
- "star_count": 93555,
- "rank": 8,
+ "pull_count": 564665,
+ "pull_rank": 11,
+ "push_count": 1514203,
+ "push_rank": 12,
+ "star_count": 982634,
+ "star_rank": 16,
"sloc": 2836,
"files": 20,
"author_name": "Masahiro Wakame",
"author_url": "https://github.com/vvakame",
+ "so_count": 78405,
+ "so_rank": 17,
"lloc": 0
},
"vhdl": {
"perf1": 3,
"perf2": 9,
"perf3": 3342,
- "star_count": 217,
- "rank": 52,
+ "pull_count": 240,
+ "pull_rank": 56,
+ "push_count": 20559,
+ "push_rank": 52,
+ "star_count": 4913,
+ "star_rank": 51,
"sloc": 4258,
"files": 19,
"author_name": "Dov Murik",
"author_url": "https://github.com/dubek",
+ "so_count": 4585,
+ "so_rank": 44,
"lloc": 0
},
"vimscript": {
"perf1": 219,
"perf2": 1055,
"perf3": 43,
- "star_count": 10096,
- "rank": 20,
+ "pull_count": 15114,
+ "pull_rank": 39,
+ "push_count": 123978,
+ "push_rank": 37,
+ "star_count": 99613,
+ "star_rank": 28,
"sloc": 2147,
"files": 22,
"author_name": "Dov Murik",
"author_url": "https://github.com/dubek",
+ "so_count": 41,
+ "so_rank": 69,
"lloc": 12
},
"vb": {
"perf1": 14,
"perf2": 14,
"perf3": 10121,
- "star_count": 578,
- "rank": 47,
+ "pull_count": 30231,
+ "pull_rank": 35,
+ "push_count": 110855,
+ "push_rank": 38,
+ "star_count": 11085,
+ "star_rank": 47,
"sloc": 3839,
"files": 19,
"author_name": "Joel Martin",
"author_url": "https://github.com/kanaka",
+ "so_count": 123078,
+ "so_rank": 13,
"lloc": 394
},
"wasm": {
"perf1": 2,
"perf2": 10,
"perf3": 3742,
- "star_count": 365,
- "rank": 49,
+ "pull_count": 2242,
+ "pull_rank": 53,
+ "push_count": 3102,
+ "push_rank": 61,
+ "star_count": 4456,
+ "star_rank": 53,
"sloc": 5270,
"files": 26,
"author_name": "Joel Martin",
"author_url": "https://github.com/kanaka",
+ "so_count": 454,
+ "so_rank": 57,
"lloc": 0
},
"yorick": {
"perf1": 67,
"perf2": 288,
"perf3": 147,
+ "pull_count": null,
+ "pull_rank": null,
+ "push_count": null,
+ "push_rank": null,
"star_count": null,
- "rank": 68,
+ "star_rank": null,
"sloc": 2398,
"files": 19,
"author_name": "Dov Murik",
"author_url": "https://github.com/dubek",
+ "so_count": 0,
+ "so_rank": 75,
"lloc": 210
}
}
\ No newline at end of file
const readdir = promisify(require('fs').readdir)
const path = require('path')
const yaml = require('js-yaml')
+const csv = require('csvtojson')
const request = require('request-promise-native')
const exec = promisify(require('child_process').exec)
const VERBOSE = process.env['VERBOSE'] || false
const BASE_PATH = process.env['BASE_PATH'] || 'base_data.yaml'
const README_PATH = process.env['README_PATH'] || '../../README.md'
-// GitHut Pushes
-//const GITHUT_URL = 'https://raw.githubusercontent.com/madnight/githut/gh-pages/gh-push-event_eb2696.json'
-// GitHut Stars
-const GITHUT_URL = process.env['GITHUT_URL'] || 'https://raw.githubusercontent.com/madnight/githut/gh-pages/gh-star-event_e61175.json'
const MAL_PATH = process.env['MAL_PATH'] || '../../'
+// GitHut 2.0 Pull Requests
+const GITHUT_PULL_URL = process.env['GITHUT_PULL_URL'] || 'https://raw.githubusercontent.com/madnight/githut/master/src/data/gh-pull-request.json'
+// GitHut 2.0 Pushes
+const GITHUT_PUSH_URL = process.env['GITHUT_PUSH_URL'] || 'https://raw.githubusercontent.com/madnight/githut/master/src/data/gh-push-event.json'
+// GitHut 2.0 Stars
+const GITHUT_STAR_URL = process.env['GITHUT_STAR_URL'] || 'https://raw.githubusercontent.com/madnight/githut/master/src/data/gh-star-event.json'
+
+// Refresh this link using this Query page:
+// https://data.stackexchange.com/stackoverflow/query/edit/1013465
+const SO_TAG_CSV_URL = process.env['SO_TAG_CSV_URL'] || 'https://data.stackexchange.com/stackoverflow/csv/1252107'
+
const githutToNames = {
'Awk': ['GNU Awk'],
'Vim script': ['Vimscript'],
'Visual Basic': ['Visual Basic.NET'],
}
+const dirToSOTags = {
+ 'cpp': ['c++', 'c++98', 'c++11', 'c++14', 'c++17'],
+ 'coffee': ['coffeescript'],
+ 'crystal': ['crystal-lang'],
+ 'cs': ['c#', 'c#-2.0', 'c#-3.0', 'c#-4.0'],
+ 'es6': ['ecmascript-6', 'es6-promise', 'es6-modules', 'es6-class', 'reactjs'],
+ 'fsharp': ['f#', 'f#-interactive', 'f#-data', 'f#-3.0'],
+ 'factor': ['factor-lang'],
+ 'js': ['javascript', 'node.js', 'jquery', 'angular'],
+ 'logo': ['logo-lang'],
+ 'make': ['makefile'],
+ 'objpascal': ['delphi', 'freepascal', 'delphi-7', 'delphi-2007', 'delphi-2009', 'delphi-2010', 'delphi-xe', 'delphi-xe2', 'delphi-xe3', 'delphi-xe4', 'delphi-xe5', 'delphi-xe7'],
+ 'objc': ['objective-c'],
+ 'python': ['python', 'python-3.x', 'python-2.7'],
+ 'swift': ['swift2'],
+ 'swift3': ['swift3'],
+ 'swift4': ['swift', 'swift4'],
+ 'ts': ['typescript', 'typescript-generics', 'typescript2.0'],
+ 'vimscript': ['viml'],
+ 'vb': ['vb.net'],
+ 'wasm': ['webassembly'],
+}
function vlog(...args) {
if (VERBOSE) {
const baseYaml = yaml.safeLoad(await readFile(BASE_PATH, 'utf8'))
vlog(`Loading README text from '${README_PATH}`)
const readmeLines = (await readFile(README_PATH, 'utf8')).split(/\n/)
- vlog(`Downloading GitHut HTML from '${GITHUT_URL}`)
- const githutText = (await request(GITHUT_URL))
+ vlog(`Downloading GitHut Pulls HTML from '${GITHUT_PULL_URL}`)
+ const githutPullText = (await request(GITHUT_PULL_URL))
+ vlog(`Downloading GitHut Pushes HTML from '${GITHUT_PUSH_URL}`)
+ const githutPushText = (await request(GITHUT_PUSH_URL))
+ vlog(`Downloading GitHut Stars HTML from '${GITHUT_STAR_URL}`)
+ const githutStarText = (await request(GITHUT_STAR_URL))
+ vlog(`Downloading StackOverflow Tag CSV from '${SO_TAG_CSV_URL}`)
+ const soTagList = await csv().fromStream(request.get(SO_TAG_CSV_URL))
vlog(`Loading log data from '${logsPath}'`)
const logFiles = (await readdir(logsPath))
.map(x => parseInt(x))
for (const f of logFiles) {
if (!(/^[0-9]+$/.exec(f))) { continue }
const path = logsPath + "/" + f
- logData.push([await readFile(path, 'utf8'), path])
+ logData.push([await readFile(path, 'utf8'), path, f])
}
let dirs = []
'perf1': null,
'perf2': null,
'perf3': 0,
+ 'pull_count': null,
+ 'pull_rank': null,
+ 'push_count': null,
+ 'push_rank': null,
'star_count': null,
- 'rank': null,
+ 'star_rank': null,
'sloc': 0,
'files': 0}
dirs.push(d[0])
dataByName[d[1]] = data
}
+
vlog(`Processing README implementations table`)
const readme_re = /^\| \[([^\[]*)\].* \| \[([^|]*)\]\(([^|]*)\) *\| *$/
for (let row of readmeLines.filter(l => /^\| [\[]/.exec(l))) {
}
}
- vlog(`Processing GitHut data`)
- const gdata = githutText.split(/\n/)
- .map(JSON.parse)
- .filter(d => d.year === "2018" && d.quarter === '4')
- .map(d => (d.count = parseInt(d.count), d))
- .sort((a,b) => (a.count > b.count) ? -1 : a.count < b.count ? 1 : 0)
- let curRank = 1
- for (let gitem of gdata) {
- const names = githutToNames[gitem.name] || [gitem.name]
- for (let name of names) {
- if (name in dataByName) {
- dataByName[name].star_count = gitem.count
- dataByName[name].rank = curRank
- vlog(` ${dataByName[name].dir} stars: ${gitem.count}, rank: ${curRank}`)
- curRank += 1
+
+ function githutProcess(textData, kind) {
+ const gMap = textData.split(/\n/)
+ .map(JSON.parse)
+ .reduce((m, d) => (m[d.name] = parseInt(d.count) + (m[d.name] || 0), m), {})
+ const gdata = Object.entries(gMap)
+ .sort(([k1,v1],[k2,v2]) => v2 - v1)
+ let curRank = 1
+ for (let [gname, gcount] of gdata) {
+ const names = githutToNames[gname] || [gname]
+ for (let name of names) {
+ if (name in dataByName) {
+ dataByName[name][kind + '_count'] = gcount
+ dataByName[name][kind + '_rank'] = curRank
+ vlog(` ${dataByName[name].dir} count: ${gcount}, rank: ${curRank}`)
+ curRank += 1
+ } else {
+ vlog(` ignoring GitHut language ${name}`)
+ }
+ }
+ }
+ return curRank;
+ }
+ vlog(`Processing GitHut Pull Request data`)
+ githutProcess(githutPullText, 'pull')
+ vlog(`Processing GitHut Push data`)
+ githutProcess(githutPushText, 'push')
+ vlog(`Processing GitHut Stars data`)
+ githutProcess(githutStarText, 'star')
+
+
+ vlog(`Processing StackOverflow tag data`)
+ const soMap = soTagList
+ //.map(d => ({tag: d.TagName, count: parseInt(d.Rate)}))
+ //.sort((a,b) => b.count - a.count)
+ .reduce((m,d) => (m[d.TagName] = parseInt(d.Rate), m), {})
+ soMap['mal'] = 0 // NOTE/TODO: StackOverflow mal is something else
+ for (let dir of dirs) {
+ if (!('so_count' in dataByDir[dir])) {
+ dataByDir[dir]['so_count'] = 0
+ }
+ let tags = dirToSOTags[dir]
+ if (!tags) {
+ if (dir in soMap) {
+ tags = [dir]
} else {
- vlog(` ignoring GitHut language ${name}`)
+ vlog(` ${dir} not found as StackOverflow tag`)
+ tags = []
}
}
+ for (let tag of tags) {
+ if (tag in soMap) {
+ dataByDir[dir]['so_count'] += soMap[tag]
+ //vlog(` ${dir} count: ${count}`)
+ } else {
+ die(1, `${tag} not found in soMap`)
+ }
+ }
+ }
+ vlog()
+ let curRank = 1
+ let soSort = Object.values(dataByDir).sort((a,b) => b.so_count - a.so_count)
+ for (let data of soSort) {
+ data.so_rank = curRank
+ vlog(` ${data.dir} so_count: ${data.so_count}, rank: ${curRank}`)
+ curRank += 1
}
+ const maxSORank = curRank
+
vlog(`Processing log file data`)
const perf_run_re = /Running:.*\.\.\/tests\/(perf[0-9])\.mal/
const perf_num_re = /Elapsed time: ([0-9.]+) msecs|iters over 10 seconds: ([0-9]+)/
- for (let [log, file] of logData) {
+ for (let [log, file, idx] of logData) {
const dir_match = (/export IMPL=(\S+)/i).exec(log)
if (!dir_match) { die(1, `no IMPL found in ${file}`) }
const dir = dir_match[1]
data.perf3 = perfs.perf3
vlog(` ${dir}: ${perfs.perf1}, ${perfs.perf2}, ${perfs.perf3}`)
} else {
- vlog(` ${dir}: ${perfs.perf1}, ${perfs.perf2}, ${perfs.perf3} (perf3 is worse, ignoring ${file})`)
+ vlog(` ${dir}: ${perfs.perf1}, ${perfs.perf2}, ${perfs.perf3} (perf3 is worse, ignoring log ${idx})`)
}
}
+
vlog(`Gathering LOC stats`)
const stat_re = /SLOC=([0-9]+).*LLOC=([0-9]+).*in ([0-9]+) files/
process.chdir(MAL_PATH)
for (let data of dataList) {
- vlog(` gathering stats information for ${data.dir}`)
const { stdout, stderr } = await exec(`make "stats^${data.dir}"`)
const match = stat_re.exec(stdout.split(/\n/)[1])
data.sloc = parseInt(match[1], 10)
data.lloc = parseInt(match[2], 10)
data.files = parseInt(match[3], 10)
+ vlog(` ${data.dir}: sloc: ${data.sloc}, lloc: ${data.lloc}, files: ${data.files}`)
}
- vlog(`Filling in missing attributes`)
- // leave a gap between actual ranked implementations and those
- // with no rankings
- maxRank = curRank + 10
- maxPerf1 = dataList.reduce((a, d) => d.perf1 > a ? d.perf1 : a, 0)
- maxPerf2 = dataList.reduce((a, d) => d.perf2 > a ? d.perf1 : a, 0)
- for (let d of dataList) {
- if (d.rank === null) {
- vlog(` setting rank to ${maxRank} for ${d.dir}`)
- d.rank = maxRank
- }
- if (d.perf1 === null) {
- vlog(` setting perf1 to ${maxPerf1} for ${d.dir}`)
- d.perf1 = maxPerf1
- }
- if (d.perf2 === null) {
- vlog(` setting perf2 to ${maxPerf2} for ${d.dir}`)
- d.perf2 = maxPerf2
- }
- }
-
- vlog(`Adjusting perf numbers to avoid 0`)
- for (let d of dataList) {
- if (d.perf1 === 0) { d.perf1 = 0.9 }
- if (d.perf2 === 0) { d.perf2 = 0.9 }
- if (d.perf3 === 0) { d.perf3 = 0.01 }
- }
vlog(`Writing full lanaguage data to ${outPath}`)
await writeFile(outPath, JSON.stringify(dataByDir, null, 2))
]
const axisMap = {
- 'perf1': 'Perf 1',
- 'perf2': 'Perf 2',
- 'perf3': 'Perf 3',
- 'rank': 'Popularity',
- 'sloc': 'SLOC size',
- 'files': 'File count',
+ 'pull_rank': 'GH PRs',
+ 'push_rank': 'GH Pushes',
+ 'star_rank': 'GH Stars',
+ 'so_rank': 'SO Tags',
+ 'perf1': 'Perf 1',
+ 'perf2': 'Perf 2',
+ 'perf3': 'Perf 3',
+ 'sloc': 'SLOC size',
+ 'files': 'File count',
}
const colorMap = {
'syntax': 'Syntax Style',
const colorKeySet = new Set(['type_check', 'syntax', 'author_name'])
const perfSet = new Set(['perf1', 'perf2', 'perf3'])
-const invertSet = new Set(['rank', 'perf1', 'perf2'])
+const invertSet = new Set(['pull_rank', 'push_rank', 'star_rank', 'so_rank', 'perf1', 'perf2'])
const perfLogSet = new Set(['perf1', 'perf2', 'sloc', 'files'])
let cfg = {
ckey: 'syntax',
- xkey: 'rank',
+ xkey: 'star_rank',
ykey: 'perf3',
skey: 'sloc',
function malExtent(data, key) {
let extent = d3.extent(Object.values(data), d => d[key])
// pad the bottom rank so it's not on the opposite axis line
- if (key === 'rank') {
+ if (key.endsWith('_rank')) {
extent[0] = 0.99 // Setting this to 1 breaks log scale render
extent[extent.length-1] += 1
}
// Replace 0's with 0.01 to prevent divide by zero errors
if (extent[0] === 0) { extent[0] = 0.0001 }
if (extent[extent.length-1] === 0) { extent[extent.length-1] = 0.0001 }
- // For rank, perf1 and perf2 reverse the Axis range
+ // For rankings, perf1, and perf2 reverse the Axis range
if (invertSet.has(key)) {
extent.reverse()
}
const parent = document.getElementById(key + '-controls')
const ctlMap = ({
'ckey': colorMap,
- 'xkey': Object.assign({}, axisMap, {'xlog': 'Logarithmic'}),
- 'ykey': Object.assign({}, axisMap, {'ylog': 'Logarithmic'}),
+ 'xkey': Object.assign({}, axisMap, {'xlog': 'Log Scale'}),
+ 'ykey': Object.assign({}, axisMap, {'ylog': 'Log Scale'}),
'skey': axisMap,
})[key]
for (let [val, name] of Object.entries(ctlMap)) {
chart.tooltip.contentGenerator(function(obj) {
const i = obj.point.impl
return '<h3>' + i.name + '</h3>' +
- '<p class="impl-data">' +
- '<b>Syntax Style</b>: ' + i.syntax + '<br>' +
- '<b>Type Discipline</b>: ' + i.type_check + '<br>' +
- '<b>Github Stars</b>: ' + (i.star_count || 'unknown') + '<br>' +
- '<b>GitHut Relative Rank</b>: ' + i.rank + '<br>' +
- '<br>' +
- '<b>Perf 1</b>: ' + i.perf1 + ' ms<br>' +
- '<b>Perf 2</b>: ' + i.perf2 + ' ms<br>' +
- '<b>Perf 3</b>: ' + i.perf3 + ' iters / 10 sec<br>' +
- '<b>SLOC</b>: ' + i.sloc + ' lines<br>' +
- //'<b>Author</b>: <a href="' + i.author_url + '">' +
- //i.author_name + '</a><br>' +
- '<b>Author</b>: ' + i.author_name + '<br>' +
+ '<ul class="impl-data">' +
+ '<li><b>Syntax Style</b>: ' + i.syntax + '<br>' +
+ '<li><b>Type Discipline</b>: ' + i.type_check + '<br>' +
+ '<li><b>GitHub</b>:' +
+ ' <ul>' +
+ ' <li><b>PR Count</b>: ' + (i.pull_count || 'unknown') + '<br>' +
+ ' <li><b>PR Rank</b>: ' + i.pull_rank + '<br>' +
+ ' <li><b>Push Count</b>: ' + (i.push_count || 'unknown') + '<br>' +
+ ' <li><b>Push Rank</b>: ' + i.push_rank + '<br>' +
+ ' <li><b>Star Count</b>: ' + (i.star_count || 'unknown') + '<br>' +
+ ' <li><b>Star Rank</b>: ' + i.star_rank + '<br>' +
+ ' </ul>' +
+ '<li><b>StackOverflow</b>:' +
+ ' <ul>' +
+ ' <li><b>Tag Count</b>: ' + (i.so_count || 'unknown') + '<br>' +
+ ' <li><b>Tag Rank</b>: ' + i.so_rank + '<br>' +
+ ' </ul>' +
+ '<li><br>' +
+ '<li><b>Perf 1</b>: ' + i.perf1 + ' ms<br>' +
+ '<li><b>Perf 2</b>: ' + i.perf2 + ' ms<br>' +
+ '<li><b>Perf 3</b>: ' + i.perf3 + ' iters / 10 sec<br>' +
+ '<li><b>SLOC</b>: ' + i.sloc + ' lines<br>' +
+ '<li><b>Author</b>: ' + i.author_name + '<br>' +
' ' + i.author_url.replace(/https?:\/\//, '') + '<br>' +
- '</p>'
+ '</ul>'
})
+
+ // Load and mangle the data
d3.json("all_data.json", function (error, data) {
allData = data
+
+ console.log(`Filling in missing data attributes`)
+ const dataList = Object.values(allData)
+ // leave a gap between ranked impls and those with no rank
+ const rankGap = 10
+ const maxPullRank = Math.max(...dataList.map(d => d.pull_rank))
+ const maxPushRank = Math.max(...dataList.map(d => d.push_rank))
+ const maxStarRank = Math.max(...dataList.map(d => d.star_rank))
+ const maxSORank = Math.max(...dataList.map(d => d.so_rank))
+ const maxPerf1 = dataList.reduce((a, d) => d.perf1 > a ? d.perf1 : a, 0)
+ const maxPerf2 = dataList.reduce((a, d) => d.perf2 > a ? d.perf1 : a, 0)
+ for (let d of dataList) {
+ if (d.pull_rank === null) {
+ d.pull_rank = maxPullRank + rankGap
+ console.log(` set pull_rank to ${d.pull_rank} for ${d.dir}`)
+ }
+ if (d.push_rank === null) {
+ d.push_rank = maxPushRank + rankGap
+ console.log(` set push_rank to ${d.push_rank} for ${d.dir}`)
+ }
+ if (d.star_rank === null) {
+ d.star_rank = maxStarRank + rankGap
+ console.log(` set star_rank to ${d.star_rank} for ${d.dir}`)
+ }
+ if (d.so_count === 0) {
+ d.so_rank = maxSORank + rankGap
+ console.log(` set so_rank to ${d.so_rank} for ${d.dir}`)
+ }
+ if (d.perf1 === null) {
+ d.perf1 = maxPerf1
+ console.log(` set perf1 to ${maxPerf1} for ${d.dir}`)
+ }
+ if (d.perf2 === null) {
+ d.perf2 = maxPerf2
+ console.log(` set perf2 to ${maxPerf2} for ${d.dir}`)
+ }
+ }
+
+ console.log(`Adjusting perf numbers to avoid 0`)
+ for (let d of dataList) {
+ if (d.perf1 === 0) { d.perf1 = 0.9 }
+ if (d.perf2 === 0) { d.perf2 = 0.9 }
+ if (d.perf3 === 0) { d.perf3 = 0.01 }
+ }
+
// NOTE: TODO: major hack to workaround bug with switching
// to/from logarithmic mode. Seems to require at least one
// value to be less than 1 for it to work
allData.rpython.perf2 = 0.9
+
updateGraphData()
})
+
return chart
})
#show {
display: none;
}
- .impl-data {
+ .impl-data, .impl-data ul {
text-align: left !important;
+ list-style: none;
+ padding: 0;
+ margin: 5;
+ }
+ .impl-data ul {
+ margin: 0 0 0 15;
}
#title {
text-align: center;
"description": "Graph Mal Languages",
"dependencies": {
"js-yaml": "3.12.2",
+ "csvtojson": "2.0.8",
"request": "2.88.0",
"request-promise-native": "1.0.7"
}