diff options
Diffstat (limited to 'vendor/github.com/tdewolff/minify/benchmarks/sample_blogpost.html')
-rw-r--r-- | vendor/github.com/tdewolff/minify/benchmarks/sample_blogpost.html | 580 |
1 files changed, 580 insertions, 0 deletions
diff --git a/vendor/github.com/tdewolff/minify/benchmarks/sample_blogpost.html b/vendor/github.com/tdewolff/minify/benchmarks/sample_blogpost.html new file mode 100644 index 0000000..f0b977f --- /dev/null +++ b/vendor/github.com/tdewolff/minify/benchmarks/sample_blogpost.html @@ -0,0 +1,580 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="UTF-8"> + <title>research!rsc: My Go Resolutions for 2017</title> + <link rel="alternate" type="application/atom+xml" title="research!rsc - Atom" href="http://research.swtch.com/feed.atom" /> + +<link href='https://fonts.googleapis.com/css?family=Inconsolata:400,700' rel='stylesheet' type='text/css'> +<script type="text/javascript" src="https://use.typekit.com/skm6yij.js"></script> +<script type="text/javascript">try{Typekit.load();}catch(e){}</script> +<style> + body { + padding: 0; + margin: 0; + font-size: 100%; + } + .header { + height: 1.25em; + background-color: #dff; + margin: 0; + padding: 0.1em 0.1em 0.2em; + border-top: 1px solid black; + border-bottom: 1px solid #8ff; + } + .header h3 { + margin: 0; + padding: 0 2em; + display: inline-block; + padding-right: 2em; + font-style: italic; + font-family: "adobe-text-pro" !important; + font-size: 90%; + } + .rss { + float: right; + padding-top: 0.2em; + padding-right: 2em; + display: none; + } + .toc { + margin-top: 2em; + } + .toc-title { + font-family: "caflisch-script-pro"; + font-size: 300%; + line-height: 50%; + } + .toc-subtitle { + display: block; + margin-bottom: 1em; + font-size: 83%; + } + @media only screen and (max-width: 550px) { .toc-subtitle { display: none; } } + .header h3 a { + color: black; + } + .header h4 { + margin: 0; + padding: 0; + display: inline-block; + font-weight: normal; + font-size: 83%; + } + @media only screen and (max-width: 550px) { .header h4 { display: none; } } + .main { + padding: 0 2em; + } + @media only screen and (max-width: 479px) { .article { font-size: 120%; } } + .article h1 { + text-align: center; + } + .article h1, .article h2, .article h3 { + font-family: 'Myriad Pro'; + } + .normal { + font-size: medium; + font-weight: normal; + } + .when { + text-align: center; + font-size: 100%; + margin: 0; + padding: 0; + } + .when p { + margin: 0; + padding: 0; + } + .article h2 { + font-size: 100%; + padding-top: 0.25em; + } + pre { + margin-left: 4em; + margin-right: 4em; + } + pre, code { + font-family: 'Inconsolata', monospace; + font-size: 100%; + } + .footer { + margin-top: 10px; + font-size: 83%; + font-family: sans-serif; + } + .comments { + margin-top: 2em; + background-color: #ffe; + border-top: 1px solid #aa4; + border-left: 1px solid #aa4; + border-right: 1px solid #aa4; + } + .comments-header { + padding: 0 5px 0 5px; + } + .comments-header p { + padding: 0; + margin: 3px 0 0 0; + } + .comments-body { + padding: 5px 5px 5px 5px; + } + #plus-comments { + border-bottom: 1px dotted #ccc; + } + .plus-comment { + width: 100%; + font-size: 14px; + border-top: 1px dotted #ccc; + } + .me { + background-color: #eec; + } + .plus-comment ul { + margin: 0; + padding: 0; + list-style: none; + width: 100%; + display: inline-block; + } + .comment-when { + color:#999; + width:auto; + padding:0 5px; + } + .old { + font-size: 83%; + } + .plus-comment ul li { + display: inline-block; + vertical-align: top; + margin-top: 5px; + margin-bottom: 5px; + padding: 0; + } + .plus-icon { + width: 45px; + } + .plus-img { + float: left; + margin: 4px 4px 4px 4px; + width: 32px; + height: 32px; + } + .plus-comment p { + margin: 0; + padding: 0; + } + .plus-clear { + clear: left; + } + .toc-when { + font-size: 83%; + color: #ccc; + } + .toc { + list-style: none; + } + .toc li { + margin-bottom: 0.5em; + } + .toc-head { + margin-bottom: 1em !important; + font-size: 117%; + } + .toc-summary { + margin-left: 2em; + } + .favorite { + font-weight: bold; + } + .article p { + line-height: 144%; + } + sup, sub { + vertical-align: baseline; + position: relative; + font-size: 83%; + } + sup { + bottom: 1ex; + } + sub { + top: 0.8ex; + } + + .main { + position: relative; + margin: 0 auto; + padding: 0; + width: 900px; + } + @media only screen and (min-width: 768px) and (max-width: 959px) { .main { width: 708px; } } + @media only screen and (min-width: 640px) and (max-width: 767px) { .main { width: 580px; } } + @media only screen and (min-width: 480px) and (max-width: 639px) { .main { width: 420px; } } + @media only screen and (max-width: 479px) { .main { width: 300px; } } + +</style> + + </head> + <body> + +<div class="header"> + <h3><a href="/">research!rsc</a></h3> + <h4>Thoughts and links about programming, + by <a href="https://swtch.com/~rsc/" rel="author">Russ Cox</a> </h4> + <a class="rss" href="/feed.atom"><img src="/feed-icon-14x14.png" /></a> +</div> + + <div class="main"> + <div class="article"> + <h1>My Go Resolutions for 2017 + <div class="normal"> + <div class="when"> + + Posted on Wednesday, January 18, 2017. + + + </div> + </div> + </h1> + <p class=lp>’Tis the season for resolutions, +and I thought it would make sense to write a little +about what I hope to work on this year as far as Go is concerned.</p> + +<p class=pp>My goal every year is to <em>help Go developers</em>. +I want to make sure that the work we do on the Go team +has a significant, positive impact on Go developers. +That may sound obvious, but there are a variety of common ways to fail to achieve that: +for example, spending too much time cleaning up or optimizing code that doesn’t need it; +responding only to the most common or recent complaints or requests; +or focusing too much on short-term improvements. +It’s important to step back and make sure we’re focusing +our development work where it does the most good.</p> + +<p class=pp>This post outlines a few of my own major focuses for this year. +This is only my personal list, not the Go team’s list.</p> + +<p class=pp>One reason for posting this is to gather feedback. +If these spark any ideas or suggestions of your own, +please feel free to comment below or on the linked GitHub issues.</p> + +<p class=pp>Another reason is to make clear that I’m aware of these issues as important. +I think too often people interpret lack of action by the Go team +as a signal that we think everything is perfect, when instead +there is simply other, higher priority work to do first.</p> + +<h2><a name="alias"></a>Type aliases</h2> + +<p class=lp>There is a recurring problem with moving types +from one package to another during large codebase refactorings. +We tried to solve it last year with <a href="https://golang.org/issue/16339">general aliases</a>, +which didn’t work for at least two reasons: we didn’t explain the change well enough, +and we didn’t deliver it on time, so it wasn’t ready for Go 1.8. +Learning from that experience, +I <a href="https://www.youtube.com/watch?v=h6Cw9iCDVcU">gave a talk</a> +and <a href="https://talks.golang.org/2016/refactor.article">wrote an article</a> +about the underlying problem, +and that started a <a href="https://golang.org/issue/18130">productive discussion</a> +on the Go issue tracker about the solution space. +It looks like more limited <a href="https://golang.org/design/18130-type-alias">type aliases</a> +are the right next step. +I want to make sure those land smoothly in Go 1.9. <a href="https://golang.org/issue/18130">#18130</a>.</p> + +<h2><a name="package"></a>Package management</h2> + +<p class=lp>I designed the Go support for downloading published packages +(“goinstall”, which became “go get”) in February 2010. +A lot has happened since then. +In particular, other language ecosystems have really raised the bar +for what people expect from package management, +and the open source world has mostly agreed on +<a href="http://semver.org/">semantic versioning</a>, which provides a useful base +for inferring version compatibility. +Go needs to do better here, and a group of contributors have been +<a href="https://blog.gopheracademy.com/advent-2016/saga-go-dependency-management/">working on a solution</a>. +I want to make sure these ideas are integrated well +into the standard Go toolchain and to make package management +a reason that people love Go.</p> + +<h2><a name="build"></a>Build improvements</h2> + +<p class=lp>There are a handful of shortcomings in the design of +the go command’s build system that are overdue to be fixed. +Here are three representative examples that I intend to +address with a bit of a redesign of the internals of the go command.</p> + +<p class=pp>Builds can be too slow, +because the go command doesn’t cache build results as aggressively as it should. +Many people don’t realize that <code>go</code> <code>install</code> saves its work while <code>go</code> <code>build</code> does not, +and then they run repeated <code>go</code> <code>build</code> commands that are slow +because the later builds do more work than they should need to. +The same for repeated <code>go</code> <code>test</code> without <code>go</code> <code>test</code> <code>-i</code> when dependencies are modified. +All builds should be as incremental as possible. +<a href="https://golang.org/issue/4719">#4719</a>.</p> + +<p class=pp>Test results should be cached too: +if none of the inputs to a test have changed, +then usually there is no need to rerun the test. +This will make it very cheap to run “all tests” when little or nothing has changed. +<a href="https://golang.org/issue/11193">#11193</a>.</p> + +<p class=pp>Work outside GOPATH should be supported nearly as well +as work inside GOPATH. +In particular, it should be possible to <code>git</code> <code>clone</code> a repo, +<code>cd</code> into it, and run <code>go</code> commands and have them work fine. +Package management only makes that more important: +you’ll need to be able to work on different versions of a package (say, v1 and v2) +without having entirely separate GOPATHs for them. +<a href="https://golang.org/issue/17271">#17271</a>.</p> + +<h2><a name="corpus"></a>Code corpus</h2> + +<p class=lp>I think it helped to have concrete examples from real projects +in the talk and article I prepared about codebase refactoring (see <a href="#alias">above</a>). +We’ve also defined that <a href="https://golang.org/src/cmd/vet/README">additions to vet</a> +must target problems that happen frequently in real programs. +I’d like to see that kind of analysis of actual practice—examining +the effects on and possible improvements to real programs—become a +standard way we discuss and evaluate changes to Go.</p> + +<p class=pp>Right now there’s not an agreed-upon representative corpus of code to use for +those analyses: everyone must first create their own, which is too much work. +I’d like to put together a single, self-contained Git repo people can check out that +contains our official baseline corpus for those analyses. +A possible starting point could be the top 100 Go language repos +on GitHub by stars or forks or both.</p> + +<h2><a name="vet"></a>Automatic vet</h2> + +<p class=lp>The Go distribution ships with this powerful tool, +<a href="https://golang.org/cmd/vet/"><code>go</code> <code>vet</code></a>, +that points out correctness bugs. +We have a high bar for checks, so that when vet speaks, you should listen. +But everyone has to remember to run it. +It would be better if you didn’t have to remember. +In particular, I think we could probably run vet +in parallel with the final compile and link of the test binary +during <code>go</code> <code>test</code> without slowing the compile-edit-test cycle at all. +If we can do that, and if we limit the enabled vet checks to a subset +that is essentially 100% accurate, +we can make passing vet a precondition for running a test at all. +Then developers don’t need to remember to run <code>go</code> <code>vet</code>. +They run <code>go</code> <code>test</code>, +and once in a while vet speaks up with something important +and avoids a debugging session. +<a href="https://golang.org/issue/18084">#18084</a>, +<a href="https://golang.org/issue/18085">#18085</a>.</p> + +<h2><a name="error"></a>Errors & best practices</h2> + +<p class=lp>Part of the intended contract for error reporting in Go is that functions +include relevant available context, including the operation being attempted +(such as the function name and its arguments). +For example, this program:</p> + +<pre><code>err := os.Remove("/tmp/nonexist") +fmt.Println(err) +</code></pre> + +<p class=lp>prints this output:</p> + +<pre><code>remove /tmp/nonexist: no such file or directory +</code></pre> + +<p class=lp>Not enough Go code adds context like <code>os.Remove</code> does. Too much code does only</p> + +<pre><code>if err != nil { + return err +} +</code></pre> + +<p class=lp>all the way up the call stack, +discarding useful context that should be reported +(like <code>remove</code> <code>/tmp/nonexist:</code> above). +I would like to try to understand whether our expectations +for including context are wrong, or if there is something +we can do to make it easier to write code that returns better errors.</p> + +<p class=pp>There are also various discussions in the community about +agreed-upon interfaces for stripping error context. +I would like to try to understand when that makes sense and +whether we should adopt an official recommendation.</p> + +<h2><a name="context"></a>Context & best practices</h2> + +<p class=lp>We added the new <a href="https://golang.org/pkg/context/">context package</a> +in Go 1.7 for holding request-scoped information like +<a href="https://blog.golang.org/context">timeouts, cancellation state, and credentials</a>. +An individual context is immutable (like an individual string or int): +it is only possible to derive a new, updated context and +pass that context explicitly further down the call stack or +(less commonly) back up to the caller. +The context is now carried through APIs such as +<a href="https://golang.org/pkg/database/sql">database/sql</a> +and +<a href="https://golang.org/pkg/net/http">net/http</a>, +mainly so that those can stop processing a request when the caller +is no longer interested in the result. +Timeout information is appropriate to carry in a context, +but—to use a <a href="https://golang.org/issue/18284">real example we removed</a>—database options +are not, because they are unlikely to apply equally well to all possible +database operations carried out during a request. +What about the current clock source, or logging sink? +Is either of those appropriate to store in a context? +I would like to try to understand and characterize the +criteria for what is and is not an appropriate use of context.</p> + +<h2><a name="memory"></a>Memory model</h2> + +<p class=lp>Go’s <a href="https://golang.org/ref/mem">memory model</a> is intentionally low-key, +making few promises to users, compared to other languages. +In fact it starts by discouraging people from reading the rest of the document. +At the same time, it demands more of the compiler than other languages: +in particular, a race on an integer value is not sufficient license +for your program to misbehave in arbitrary ways. +But there are some complete gaps, in particular no mention of +the <a href="https://golang.org/pkg/sync/atomic/">sync/atomic package</a>. +I think the core compiler and runtime developers all agree +that the behavior of those atomics should be roughly the same as +C++ seqcst atomics or Java volatiles, +but we still need to write that down carefully in the memory model, +and probably also in a long blog post. +<a href="https://golang.org/issue/5045">#5045</a>, +<a href="https://golang.org/issue/7948">#7948</a>, +<a href="https://golang.org/issue/9442">#9442</a>.</p> + +<h2><a name="immutability"></a>Immutability</h2> + +<p class=lp>The <a href="https://golang.org/doc/articles/race_detector.html">race detector</a> +is one of Go’s most loved features. +But not having races would be even better. +I would love it if there were some reasonable way to integrate +<a href="https://www.google.com/search?q=%22reference+immutability%22">reference immutability</a> into Go, +so that programmers can make clear, checked assertions about what can and cannot +be written and thereby eliminate certain races at compile time. +Go already has one immutable type, <code>string</code>; it would +be nice to retroactively define that +<code>string</code> is a named type (or type alias) for <code>immutable</code> <code>[]byte</code>. +I don’t think that will happen this year, +but I’d like to understand the solution space better. +Javari, Midori, Pony, and Rust have all staked out interesting points +in the solution space, and there are plenty of research papers +beyond those.</p> + +<p class=pp>In the long-term, if we could statically eliminate the possibility of races, +that would eliminate the need for most of the memory model. +That may well be an impossible dream, +but again I’d like to understand the solution space better.</p> + +<h2><a name="generics"></a>Generics</h2> + +<p class=lp>Nothing sparks more <a href="https://research.swtch.com/dogma">heated arguments</a> +among Go and non-Go developers than the question of whether Go should +have support for generics (or how many years ago that should have happened). +I don’t believe the Go team has ever said “Go does not need generics.” +What we <em>have</em> said is that there are higher-priority issues facing Go. +For example, I believe that better support for package management +would have a much larger immediate positive impact on most Go developers +than adding generics. +But we do certainly understand that for a certain subset of Go use cases, +the lack of parametric polymorphism is a significant hindrance.</p> + +<p class=pp>Personally, I would like to be able to write general channel-processing +functions like:</p> + +<pre><code>// Join makes all messages received on the input channels +// available for receiving from the returned channel. +func Join(inputs ...<-chan T) <-chan T + +// Dup duplicates messages received on c to both c1 and c2. +func Dup(c <-chan T) (c1, c2 <-chan T) +</code></pre> + +<p class=lp>I would also like to be able to write +Go support for high-level data processing abstractions, +analogous to +<a href="https://research.google.com/pubs/archive/35650.pdf">FlumeJava</a> or +C#’s <a href="https://en.wikipedia.org/wiki/Language_Integrated_Query">LINQ</a>, +in a way that catches type errors at compile time instead of at run time. +There are also any number of data structures or generic algorithms +that might be written, +but I personally find these broader applications more compelling.</p> + +<p class=pp>We’ve <a href="https://research.swtch.com/generic">struggled</a> off and on +<a href="https://golang.org/design/15292-generics">for years</a> +to find the right way to add generics to Go. +At least a few of the past proposals got hung up on trying to design +something that provided both general parametric polymorphism +(like <code>chan</code> <code>T</code>) and also a unification of <code>string</code> and <code>[]byte</code>. +If the latter is handled by parameterization over immutability, +as described in the previous section, then maybe that simplifies +the demands on a design for generics.</p> + +<p class=pp>When I first started thinking about generics for Go in 2008, +the main examples to learn from were C#, Java, Haskell, and ML. +None of the approaches in those languages seemed like a +perfect fit for Go. +Today, there are newer attempts to learn from as well, +including Dart, Midori, Rust, and Swift.</p> + +<p class=pp>It’s been a few years since we ventured out and explored the design space. +It is probably time to look around again, +especially in light of the insight about mutability and +the additional examples set by newer languages. +I don’t think generics will happen this year, +but I’d like to be able to say I understand the solution space better.</p> + + </div> + + + <div id="disqus_thread"></div> + <script> + var disqus_config = function () { + this.page.url = "https://research.swtch.com/go2017"; + this.page.identifier = "blog/go2017"; + }; + (function() { + var d = document, s = d.createElement('script'); + s.src = '//swtch.disqus.com/embed.js'; + s.setAttribute('data-timestamp', +new Date()); + (d.head || d.body).appendChild(s); + })(); + </script> + <noscript>Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript> + </div> + + </div> + + +<script type="text/javascript"> +var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www."); +document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E")); +</script> +<script type="text/javascript"> +var pageTracker = _gat._getTracker("UA-3319603-2"); +pageTracker._initData(); +pageTracker._trackPageview(); +</script> + + + + </body> +</html> + + + + + + + + + + + + + + + + |