Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] implement group_voids #2945

Closed
wants to merge 2 commits into from
Closed

Conversation

alexlamsl
Copy link
Collaborator

fixes #2585

/cc @kzc @Skalman

@alexlamsl
Copy link
Collaborator Author

node test/benchmark.js -cm node test/benchmark.js -cm group_voids
https://code.jquery.com/jquery-3.2.1.js
- parse: 0.234s
- rename: 0.219s
- compress: 1.500s
- scope: 0.078s
- mangle: 0.140s
- properties: 0.000s
- output: 0.079s
- total: 2.250s

Original: 268039 bytes
Uglified: 86047 bytes
GZipped:  30058 bytes
SHA1 sum: e3759e2b87ceb0391b0e50c8c3421a1c9ac5abab

https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.4/angular.js
- parse: 0.500s
- rename: 0.281s
- compress: 2.594s
- scope: 0.171s
- mangle: 0.313s
- properties: 0.000s
- output: 0.156s
- total: 4.015s

Original: 1249863 bytes
Uglified: 173596 bytes
GZipped:  59986 bytes
SHA1 sum: b68526f9c8d8dfa56ada736f7f65afbab31c0b71

https://cdnjs.cloudflare.com/ajax/libs/mathjs/3.9.0/math.js
- parse: 0.906s
- rename: 0.547s
- compress: 5.437s
- scope: 0.172s
- mangle: 0.328s
- properties: 0.000s
- output: 0.235s
- total: 7.625s

Original: 1590107 bytes
Uglified: 466497 bytes
GZipped:  118809 bytes
SHA1 sum: 9b97bace1201003ddbe9d83f4891c5ba39f425fc

https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.js
- parse: 0.093s
- rename: 0.063s
- compress: 0.562s
- scope: 0.032s
- mangle: 0.062s
- properties: 0.000s
- output: 0.031s
- total: 0.843s

Original: 69707 bytes
Uglified: 36833 bytes
GZipped:  9579 bytes
SHA1 sum: df38148a95914060e20f4495d5767e06ba59ef3a

https://unpkg.com/[email protected]/dist/react.js
- parse: 0.500s
- rename: 0.250s
- compress: 2.375s
- scope: 0.109s
- mangle: 0.266s
- properties: 0.000s
- output: 0.140s
- total: 3.640s

Original: 701412 bytes
Uglified: 205113 bytes
GZipped:  62268 bytes
SHA1 sum: e49d727b1f64ba3ceb32135f1708a66718f117cf

http://builds.emberjs.com/tags/v2.11.0/ember.prod.js
- parse: 0.843s
- rename: 0.625s
- compress: 4.047s
- scope: 0.172s
- mangle: 0.422s
- properties: 0.000s
- output: 0.250s
- total: 6.359s

Original: 1852178 bytes
Uglified: 525929 bytes
GZipped:  129044 bytes
SHA1 sum: 6258c8317f1b121e6f1d08d8ed2e7d391a06735f

https://cdn.jsdelivr.net/lodash/4.17.4/lodash.js
- parse: 0.250s
- rename: 0.218s
- compress: 3.094s
- scope: 0.063s
- mangle: 0.140s
- properties: 0.000s
- output: 0.063s
- total: 3.828s

Original: 539590 bytes
Uglified: 69574 bytes
GZipped:  24884 bytes
SHA1 sum: 0f828505bbb3a1b86b2207f35aa092b951b37ec2

https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.js
- parse: 0.562s
- rename: 0.375s
- compress: 3.563s
- scope: 0.125s
- mangle: 0.250s
- properties: 0.000s
- output: 0.140s
- total: 5.015s

Original: 451131 bytes
Uglified: 211566 bytes
GZipped:  71027 bytes
SHA1 sum: 8d5326b2769c2d66f6b47439d482b09f74d35a48

https://raw.githubusercontent.com/kangax/html-minifier/v3.5.7/dist/htmlminifier.js
- parse: 0.843s
- rename: 0.453s
- compress: 4.844s
- scope: 0.157s
- mangle: 0.359s
- properties: 0.000s
- output: 0.328s
- total: 6.984s

Original: 1063075 bytes
Uglified: 507989 bytes
GZipped:  157987 bytes
SHA1 sum: f86ae107da3ac2453d5f87c7fad4d84c580e4071
https://code.jquery.com/jquery-3.2.1.js
- parse: 0.234s
- rename: 0.203s
- compress: 1.516s
- scope: 0.078s
- mangle: 0.187s
- properties: 0.000s
- output: 0.141s
- total: 2.359s

Original: 268039 bytes
Uglified: 85634 bytes
GZipped:  30025 bytes
SHA1 sum: cc3f78d289a139e631c916b7aa7ffc34e34c3857

https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.4/angular.js
- parse: 0.578s
- rename: 0.312s
- compress: 2.813s
- scope: 0.109s
- mangle: 0.250s
- properties: 0.000s
- output: 0.141s
- total: 4.203s

Original: 1249863 bytes
Uglified: 173235 bytes
GZipped:  59967 bytes
SHA1 sum: f8453fbb34f8c330621ccb240a2f30812f89becb

https://cdnjs.cloudflare.com/ajax/libs/mathjs/3.9.0/math.js
- parse: 0.953s
- rename: 0.593s
- compress: 5.579s
- scope: 0.156s
- mangle: 0.406s
- properties: 0.000s
- output: 0.235s
- total: 7.922s

Original: 1590107 bytes
Uglified: 465760 bytes
GZipped:  118759 bytes
SHA1 sum: 5a969db234bb0a10a7945150419c15c2be544997

https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.js
- parse: 0.093s
- rename: 0.063s
- compress: 0.500s
- scope: 0.015s
- mangle: 0.079s
- properties: 0.000s
- output: 0.046s
- total: 0.796s

Original: 69707 bytes
Uglified: 36831 bytes
GZipped:  9578 bytes
SHA1 sum: edafaece75311aa144c95bdfbd66fa534c1eda4e

https://unpkg.com/[email protected]/dist/react.js
- parse: 0.546s
- rename: 0.250s
- compress: 2.469s
- scope: 0.094s
- mangle: 0.250s
- properties: 0.000s
- output: 0.125s
- total: 3.734s

Original: 701412 bytes
Uglified: 204820 bytes
GZipped:  62245 bytes
SHA1 sum: 40a6dc8f404ae7b0d7db3761b045e8c21d226bb2

http://builds.emberjs.com/tags/v2.11.0/ember.prod.js
- parse: 0.875s
- rename: 0.593s
- compress: 3.969s
- scope: 0.250s
- mangle: 0.391s
- properties: 0.000s
- output: 0.234s
- total: 6.312s

Original: 1852178 bytes
Uglified: 523456 bytes
GZipped:  128918 bytes
SHA1 sum: 4dfe50a1212e5f69e9d417e8bbfa9749fd6e0ca6

https://cdn.jsdelivr.net/lodash/4.17.4/lodash.js
- parse: 0.265s
- rename: 0.188s
- compress: 2.906s
- scope: 0.078s
- mangle: 0.203s
- properties: 0.000s
- output: 0.078s
- total: 3.718s

Original: 539590 bytes
Uglified: 69574 bytes
GZipped:  24884 bytes
SHA1 sum: 0f828505bbb3a1b86b2207f35aa092b951b37ec2

https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.js
- parse: 0.593s
- rename: 0.360s
- compress: 3.578s
- scope: 0.109s
- mangle: 0.281s
- properties: 0.000s
- output: 0.141s
- total: 5.062s

Original: 451131 bytes
Uglified: 211521 bytes
GZipped:  71018 bytes
SHA1 sum: a583f49d59d9714f0239c6cb0bfc0963bbacea32

https://raw.githubusercontent.com/kangax/html-minifier/v3.5.7/dist/htmlminifier.js
- parse: 0.921s
- rename: 0.547s
- compress: 4.782s
- scope: 0.156s
- mangle: 0.500s
- properties: 0.000s
- output: 0.266s
- total: 7.172s

Original: 1063075 bytes
Uglified: 507515 bytes
GZipped:  158008 bytes
SHA1 sum: a0355a9451c14c56d9431578ab7d8fcd52bec519

@alexlamsl alexlamsl changed the title implement group_voids [WIP] implement group_voids Feb 22, 2018
@kzc
Copy link
Contributor

kzc commented Feb 22, 2018

Not keen on this approach. The AST shouldn't be altered in the mangle phase other than changing the symbol. The transform ought to be in compress after the last pass and should be able to be used without mangle for test case debugging/diff purposes.

@alexlamsl
Copy link
Collaborator Author

@kzc I understand your viewpoint - any idea how to separate part of this workload to Compressor?

Bear in mind that the other attempts always end up with measurably worse gzip results.

slightly less improved gzip results
@kzc
Copy link
Contributor

kzc commented Feb 22, 2018

any idea how to separate part of this workload to Compressor?

Why is it that creating a new variable (u, u$1, etc) in the Compressor wouldn't produce an optimal symbol in mangle?

@alexlamsl
Copy link
Collaborator Author

If I know the underlying cause to that question other than the observable facts, I would have more luck with #2219 😅

@alexlamsl
Copy link
Collaborator Author

My best guess so far is because variable name assignments from mangle is top-down, so injecting a new variable would cause an avalanche in the child scopes.

@Skalman
Copy link
Contributor

Skalman commented Feb 22, 2018

@kzc commented that this type of change can mess with the JIT, since this change introduces capturing of variables. I think that means that group_voids can't ever be enabled by default.
Ref #2585 (comment)

@Skalman
Copy link
Contributor

Skalman commented Feb 22, 2018

Bear in mind that the other attempts always end up with measurably worse gzip results.

@alexlamsl Has this actually been tested? None of the experiments I did introduce capturing variables between functions (which is the reason why my Uglified (and likely Gzip) numbers were worse).

@alexlamsl
Copy link
Collaborator Author

Has this actually been tested?

I am referring to all the attempts under #2912 - capturing variable or not is moot, because it's the variable name assignment which is causing the gzip result to deteriorate.

@alexlamsl
Copy link
Collaborator Author

I'm not concerned about theoretical or version-to-version variations on runtime performance - correctness and uglified sizes are the primary goals.

@kzc
Copy link
Contributor

kzc commented Feb 22, 2018

Through trial an error some undefined seed symbol can be formulated in compress to produce an optimal mangle result. Perhaps this particular symbol has to be excluded from mangle frequency consideration.

In my opinion some marginal optimizations are not worth pursuing if they negatively impact the structure and understandability of the code if there's any hope anyone other than you will produce PRs or maintain this code in the future.

@Skalman
Copy link
Contributor

Skalman commented Feb 22, 2018

@alexlamsl Maybe we're talking past one another? My understanding is that your code reuses the same variable, while all my experiments were introducing a new variable per scope.

// INPUT
function a(b) {
	var x = 1;
	if (b) return void 0;
	return function () { return void 0; };
}

// OUTPUT
// alexlamsl's version
function a(b) {
	var x = 1, u;
	if (b) return u;
	return function () { return u; };
}

// Skalman's version
function a(b) {
	var x = 1, u;
	if (b) return u;
	return function () { var u2; return u2; };
}

@kzc
Copy link
Contributor

kzc commented Feb 22, 2018

@kzc commented that this type of change can mess with the JIT, since this change introduces capturing of variables. I think that means that group_voids can't ever be enabled by default.

I assumed that this PR works within individual function scopes. If it introduces captured variables then I'd agree it shouldn't be enabled by default.

@alexlamsl
Copy link
Collaborator Author

My understanding is that your code reuses the same variable, while all my experiments were introducing a new variable per scope.

@Skalman I understand what you are talking about, and I'm pointing out that it's not the culprit for the gzip size regression. One experiment you can perform is to test your PR with --rename -c which shortens the variable names, but unlike mangle would not suffer large-scale variable name differences. You'll find that the gzip results with or without the void 0 extraction is much closer.

@Skalman
Copy link
Contributor

Skalman commented Feb 22, 2018

@alexlamsl I'd assume that the culprit is adding all the new ,u in each function, and in the case where no existing var exists, adding a new var u.

One experiment you can perform is to test your PR with --rename -c

I don't really understand how this works, but I'll try it when I have time (another day).

@alexlamsl
Copy link
Collaborator Author

@kzc the scope of variable injection doesn't matter much - I didn't go down to individual AST_Scope because it's less code to write to demonstrate the byte savings.

What I am hoping to work out is, based on the fact that this PR works, what we might be able to learn about mangle so that we can make more fundamental improvements.

@alexlamsl
Copy link
Collaborator Author

I'd assume that the culprit is adding all the new ,u in each function, and in the case where no existing var exists, adding a new var u.

I have investigated this possibility before and it wasn't the case AFAICT.

@kzc
Copy link
Contributor

kzc commented Feb 22, 2018

What I am hoping to work out is, based on the fact that this PR works, what we might be able to learn about mangle so that we can make more fundamental improvements.

I agree it would be fine to improve mangle generally, but I think this PR's savings is not compelling enough to add to the code base in light of the AST change within mangle.

@alexlamsl
Copy link
Collaborator Author

I agree it would be fine to improve mangle generally, but I think this PR's savings is not compelling enough to add to the code base in light of the AST change within mangle.

I think we are on the same page.

@alexlamsl
Copy link
Collaborator Author

As for any concerns with performance differences:

--- a/test/jetstream.js
+++ b/test/jetstream.js
@@ -96,7 +96,7 @@ if (typeof phantom == "undefined") {
     page.open(url, function(status) {
         if (status != "success") phantom.exit(1);
         page.evaluate(function() {
-            JetStream.switchToQuick();
+            JetStream.switchToLong();
             JetStream.start();
         });
     });

No statistically significant difference is measured between -mcb beautify=false,webkit and -m group_voids -cb beautify=false,webkit

@alexlamsl alexlamsl closed this Feb 23, 2018
@alexlamsl alexlamsl deleted the group_voids branch February 23, 2018 19:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

void 0 can be optimized to an unassigned variable
3 participants