Skip to content

Instantly share code, notes, and snippets.

@Isk1n
Last active May 2, 2020 12:03
Show Gist options
  • Save Isk1n/54315d74264c857856c73f18c81278dc to your computer and use it in GitHub Desktop.
Save Isk1n/54315d74264c857856c73f18c81278dc to your computer and use it in GitHub Desktop.
Plain text linkifiers comparison (work in progress) (http://jsbench.github.io/#54315d74264c857856c73f18c81278dc) #jsbench #jsperf
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Plain text linkifiers comparison (work in progress)</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/benchmark/1.0.0/benchmark.min.js"></script>
<script src="./suite.js"></script>
</head>
<body>
<h1>Open the console to view the results</h1>
<h2><code>cmd + alt + j</code> or <code>ctrl + alt + j</code></h2>
</body>
</html>
"use strict";
(function (factory) {
if (typeof Benchmark !== "undefined") {
factory(Benchmark);
} else {
factory(require("benchmark"));
}
})(function (Benchmark) {
var suite = new Benchmark.Suite;
Benchmark.prototype.setup = function () {
// Performance test of 6 linkifiers. Correctness isn't checked here
//
// Linkifiers:
//
// 1. JavaScript Linkify
// https://github.com/cowboy/javascript-linkify
//
// 2. autolink-js
// https://github.com/bryanwoods/autolink-js
//
// 3. urlize.js
// https://github.com/ljosa/urlize.js
//
// 4. Autolinker.js
// https://github.com/gregjacobs/Autolinker.js
//
// 5. Anchorme.js
// https://github.com/alexcorvi/anchorme.js
//
// 6. Linkify
// https://github.com/SoapBox/linkifyjs
//
var xhr = new XMLHttpRequest();
var scriptElementToClone = document.createElement('script');
var scriptsToLoad = [
{
title: 'linkify',
url: 'http://soapbox.github.io/linkifyjs/js/linkify/linkify.min.js'
},
{
title: 'linkify-string',
url: 'http://soapbox.github.io/linkifyjs/js/linkify/linkify-string.min.js'
},
{
title: 'anchorme',
url: 'http://alexcorvi.github.io/anchorme.js/dist/anchorme.js'
},
{
title: 'Autolinker',
url: 'http://gregjacobs.github.io/Autolinker.js/dist/Autolinker.min.js'
},
{
title: 'urlize',
url: 'https://cdn.rawgit.com/ljosa/urlize.js/master/urlize.js'
},
{
title: 'urlize_tlds',
url: 'https://raw.githubusercontent.com/ljosa/urlize.js/master/urlize_tlds.js'
},
{
title: 'autolink-js',
url: 'https://cdn.rawgit.com/bryanwoods/autolink-js/master/autolink-min.js'
},
{
title: 'javascript-linkify',
url: 'https://cdn.rawgit.com/cowboy/javascript-linkify/master/ba-linkify.min.js'
}
];
var scriptIdPrefix = 'Script';
scriptsToLoad.forEach(function(script){
if (document.getElementById(script.title + scriptIdPrefix)) {
return;
}
var scriptElement = scriptElementToClone.cloneNode(false);
scriptElement.id = script.title + scriptIdPrefix;
xhr.open('GET', script.url, false);
xhr.send();
if (xhr.status != 200) {
throw new Error(xhr.status + ': ' + xhr.statusText + ' .Failed to open ' + script.title + ' at ' + script.url);
}
scriptElement.textContent = xhr.responseText;
document.body.appendChild(scriptElement);
});
var autolinker = autolinker || new Autolinker({
newWindow: false,
phone: false,
stripPrefix: false,
stripTrailingSlash: false
});
// example text has been taken from here http://markdown-it.github.io/linkify-it/
var text="";
text += "%";
text += "% Regular links";
text += "%";
text += "My http:\/\/example.com site";
text += "My http:\/\/example.com\/ site";
text += "http:\/\/example.com\/foo_bar\/";
text += "http:\/\/user:pass@example.com:8080";
text += "http:\/\/user@example.com";
text += "http:\/\/user@example.com:8080";
text += "http:\/\/user:pass@example.com";
text += "[https](https:\/\/www.ibm.com)[mailto](mailto:someone@ibm.com) % should not catch as auth (before @ in big link)";
text += "http:\/\/example.com:8080";
text += "http:\/\/example.com\/?foo=bar";
text += "http:\/\/example.com?foo=bar";
text += "http:\/\/example.com\/#foo=bar";
text += "http:\/\/example.com#foo=bar";
text += "http:\/\/a.in";
text += "HTTP:\/\/GOOGLE.COM";
text += "http:\/\/example.invalid % don't restrict root domain when schema exists";
text += "http:\/\/inrgess2 % Allow local domains to end with digit";
text += "http:\/\/999 % ..and start with digit, and have digits only";
text += "http:\/\/host-name % local domain with dash";
text += ">>example.com % markdown blockquote";
text += ">>http:\/\/example.com % markdown blockquote";
text += "http:\/\/lyricstranslate.com\/en\/someone-you-നിന്നെ-പോലൊരാള്‍.html % With control character";
text += "";
text += "%";
text += "% localhost (only with protocol allowed)";
text += "%";
text += "\/\/localhost";
text += "\/\/test.123";
text += "http:\/\/localhost:8000?";
text += "";
text += "%";
text += "% Other protocols";
text += "%";
text += "My ssl https:\/\/example.com site";
text += "My ftp:\/\/example.com site";
text += "";
text += "%";
text += "% Neutral proto";
text += "%";
text += "My ssl \/\/example.com site";
text += "";
text += "%";
text += "% IPs";
text += "%";
text += "4.4.4.4";
text += "192.168.1.1\/abc";
text += "";
text += "%";
text += "% Fuzzy";
text += "%";
text += "test.example@http:\/\/vk.com";
text += "text:http:\/\/example.com\/";
text += "google.com";
text += "google.com: \/\/ no port";
text += "s.l.o.w.io";
text += "a-b.com";
text += "GOOGLE.COM.";
text += "google.xxx \/\/ known tld";
text += "";
text += "%";
text += "% Correct termination for . , ! ? [] {} () \"\" ''";
text += "%";
text += "(Scoped http:\/\/example.com\/foo_bar)";
text += "http:\/\/example.com\/foo_bar_(wiki)";
text += "http:\/\/foo.com\/blah_blah_[other]";
text += "http:\/\/foo.com\/blah_blah_{I'm_king}";
text += "http:\/\/foo.com\/blah_blah_I'm_king";
text += "http:\/\/www.kmart.com\/bestway-10'-x-30inch-steel-pro-frame-pool\/p-004W007538417001P";
text += "http:\/\/foo.com\/blah_blah_\"doublequoted\"";
text += "http:\/\/foo.com\/blah_blah_'singlequoted'";
text += "(Scoped like http:\/\/example.com\/foo_bar)";
text += "[Scoped like http:\/\/example.com\/foo_bar]";
text += "{Scoped like http:\/\/example.com\/foo_bar}";
text += "\"Quoted like http:\/\/example.com\/foo_bar\"";
text += "'Quoted like http:\/\/example.com\/foo_bar'";
text += "[example.com\/foo_bar.jpg)]";
text += "http:\/\/example.com\/foo_bar.jpg.";
text += "http:\/\/example.com\/foo_bar\/.";
text += "http:\/\/example.com\/foo_bar,";
text += "https:\/\/github.com\/markdown-it\/linkify-it\/compare\/360b13a733f521a8d4903d3a5e1e46c357e9d3ce...f580766349525150a80a32987bb47c2d592efc33";
text += "http:\/\/example.com\/foo_bar...";
text += "http:\/\/172.26.142.48\/viewerjs\/#..\/0529\/slides.pdf";
text += "http:\/\/example.com\/foo_bar..";
text += "http:\/\/example.com\/foo_bar?p=10.";
text += "https:\/\/www.google.ru\/maps\/@59.9393895,30.3165389,15z?hl=ru";
text += "https:\/\/www.google.com\/maps\/place\/New+York,+NY,+USA\/@40.702271,-73.9968471,11z\/data=!4m2!3m1!1s0x89c24fa5d33f083b:0xc80b8f06e177fe62?hl=en";
text += "https:\/\/www.google.com\/analytics\/web\/?hl=ru&pli=1#report\/visitors-overview\/a26895874w20458057p96934174\/";
text += "http:\/\/business.timesonline.co.uk\/article\/0,,9065-2473189,00.html";
text += "http:\/\/example.com\/123!";
text += "http:\/\/example.com\/foo--bar";
text += "";
text += "% some sites have links with trailing dashes";
text += "http:\/\/www.bloomberg.com\/news\/articles\/2015-06-26\/from-deutsche-bank-to-siemens-what-s-troubling-germany-inc-";
text += "http:\/\/example.com\/foo-with-trailing-dash-dot-.";
text += "<http:\/\/domain.com>";
text += "<http:\/\/domain.com>.";
text += "<http:\/\/domain.com\/foo>";
text += "<http:\/\/domain.com\/foo>.";
text += "<domain.com>";
text += "<domain.com>.";
text += "<domain.com\/foo>";
text += "<user@domain.com>";
text += "<user@domain.com>.";
text += "<mailto:user@domain.com>";
text += "";
text += "%";
text += "% Emails";
text += "%";
text += "test.\"foo\".bar@gmail.co.uk!";
text += "name@example.com";
text += ">>name@example.com % markdown blockquote";
text += "mailto:name@example.com";
text += "MAILTO:NAME@EXAMPLE.COM";
text += "mailto:foo_bar@example.com";
text += "foo+bar@gmail.com";
text += "192.168.1.1@gmail.com";
text += "mailto:foo@bar % explicit protocol make it valid";
text += "(foobar email@example.com)";
text += "(email@example.com foobar)";
text += "(email@example.com)";
text += "";
text += "%";
text += "% International";
text += "%";
text += "http:\/\/✪df.ws\/123";
text += "http:\/\/xn--df-oiy.ws\/123";
text += "a.ws";
text += "➡.ws\/䨹";
text += "example.com\/䨹";
text += "президент.рф";
text += "";
text += "% Links below provided by diaspora* guys, to make sure regressions will not happen.";
text += "% Those left here for historic reasons.";
text += "http:\/\/www.bürgerentscheid-krankenhäuser.de";
text += "http:\/\/www.xn--brgerentscheid-krankenhuser-xkc78d.de";
text += "http:\/\/bündnis-für-krankenhäuser.de\/wp-content\/uploads\/2011\/11\/cropped-logohp.jpg";
text += "http:\/\/xn--bndnis-fr-krankenhuser-i5b27cha.de\/wp-content\/uploads\/2011\/11\/cropped-logohp.jpg";
text += "http:\/\/ﻡﻮﻘﻋ.ﻭﺯﺍﺭﺓ-ﺍﻼﺘﺻﺍﻼﺗ.ﻢﺻﺭ\/";
text += "http:\/\/xn--4gbrim.xn----ymcbaaajlc6dj7bxne2c.xn--wgbh1c\/";
text += "";
text += "";
text += "%";
text += "% Not links";
text += "%";
text += "example.invalid";
text += "example.invalid\/";
text += "http:\/\/.example.com";
text += "http:\/\/-example.com";
text += "hppt:\/\/example.com";
text += "example.coma";
text += "-example.coma";
text += "foo.123";
text += "http:\/\/a.b--c.de\/ % `--` disabled, because collision possible";
text += "localhost % only with protocol allowed";
text += "localhost\/";
text += "\/\/\/localhost % 3 '\/' not allowed";
text += "\/\/\/test.com";
text += "\/\/test % Don't allow single level protocol-less domains to avoid false positives";
text += "";
text += "_http:\/\/example.com";
text += "_\/\/example.com";
text += "_example.com";
text += "http:\/\/example.com_";
text += "@example.com";
text += "";
text += "node.js and io.js";
text += "";
text += "http:\/\/";
text += "http:\/\/.";
text += "http:\/\/..";
text += "http:\/\/#";
text += "http:\/\/##";
text += "http:\/\/?";
text += "http:\/\/??";
text += "google.com:500000 \/\/ invalid port";
text += "show image.jpg";
text += "path:to:file.pm";
text += "\/path\/to\/file.pl";
text += "";
text += "%";
text += "% Not IPv4";
text += "%";
text += "1.2.3.4.5";
text += "1.2.3";
text += "1.2.3.400";
text += "1000.2.3.4";
text += "a1.2.3.4";
text += "1.2.3.4a";
text += "";
text += "%";
text += "% Not email";
text += "%";
text += "foo@bar % Should be at second level domain & with correct tld";
text += "mailto:bar";
console.log(text);
};
suite.add("JavaScript Linkify", function () {
// JavaScript Linkify
linkify(text);
});
suite.add("autolink-js", function () {
// autolink-js
text.autoLink();
});
suite.add("urlize.js", function () {
// urlize.js
urlize(text, {
top_level_domains: urlize.top_level_domains,
django_compatible: false
});
});
suite.add("Autolinker.js", function () {
// Autolinker.js
autolinker.link(text);
});
suite.add("Anchorme.js", function () {
// Anchorme.js
anchorme(text);
});
suite.add("Linkify", function () {
// Linkify
linkifyStr(text);
});
suite.on("cycle", function (evt) {
console.log(" - " + evt.target);
});
suite.on("complete", function (evt) {
console.log(new Array(30).join("-"));
var results = evt.currentTarget.sort(function (a, b) {
return b.hz - a.hz;
});
results.forEach(function (item) {
console.log((idx + 1) + ". " + item);
});
});
console.log("Plain text linkifiers comparison (work in progress)");
console.log(new Array(30).join("-"));
suite.run();
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment