In-Browser CSV Parsers

JavaScript performance comparison

Revision 5 of this test case created by

Preparation code

<!-- jQuery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>

<!-- CSV libraries -->
<script src="http://jquery-csv.googlecode.com/git/src/jquery.csv.js"></script>
<script src="https://rawgit.com/henix/csv.js/master/csv.js"></script>
<script>var henixCsv = CSV; // avoid namespace collision</script>
<script src="https://rawgit.com/knrz/CSV.js/master/csv.min.js"></script>
<script src="https://rawgit.com/mholt/PapaParse/master/papaparse.min.js"></script>
<script>
// Papa Parse 3.1 version of the parser
function Papa3Parser(e){function y(){while(f<n.length){if(g)break;if(u>0&&m>=u)break;if(a=='"')E();else if(l)S();else x();b()}return w()}function b(){f++;a=n[f]}function w(){if(g)B("Abort","ParseAbort","Parsing was aborted by the user's step function");if(l)B("Quotes","MissingQuotes","Unescaped or mismatched quotes");A();if(!q(s))return I()}function E(){if(P()&&!D())l=!l;else{C();if(l&&D())f++;else B("Quotes","UnexpectedQuotes","Unexpected quotes")}}function S(){if(M(f)||_(f))c++;C()}function x(){if(a==r)k();else if(M(f)){L();b()}else if(_(f))L();else if(T())N();else C()}function T(){if(!i)return false;var e=f==0||_(f-1)||M(f-2);return e&&n[f]===i}function N(){while(!M(f)&&!_(f)&&f<n.length){b()}}function C(){h[d][v]+=a}function k(){h[d].push("");v=h[d].length-1}function L(){A();c++;m++;h.push([]);d=h.length-1;k()}function A(){O();if(q(s)){if(h[d])s(I());F()}}function O(){if(h[d].length==1&&t.test(h[d][0])){if(e.keepEmptyRows)h[d].splice(0,1);else h.splice(d,1);d=h.length-1}}function M(e){return e<n.length-1&&(n[e]=="\r"&&n[e+1]=="\n"||n[e]=="\n"&&n[e+1]=="\r")}function _(e){return n[e]=="\r"||n[e]=="\n"}function D(){return!P()&&f<n.length-1&&n[f+1]=='"'}function P(){return!l&&H(f-1)||H(f+1)}function H(e){if(typeof e!="number")e=f;var t=n[e];return e<=-1||e>=n.length||t==r||t=="\r"||t=="\n"}function B(e,t,n){p.push({type:e,code:t,message:n,line:c,row:d,index:f})}function j(e){n=e;l=false;f=0,m=0,c=1;F();h=[[""]];a=n[f]}function F(){h=[];p=[];d=0;v=0}function I(){return{data:h,errors:p,meta:{lines:c,delimiter:r,aborted:g,truncated:u>0&&f<n.length}}}function q(e){return typeof e==="function"}var t=/^\s*$/;var n;var r;var i;var s;var o;var u;var a;var f;var l;var c;var h;var p;var d;var v;var m;var g=false;e=e||{};r=e.delimiter;i=e.comments;s=e.step;u=e.preview;if(typeof r!=="string"||r.length!=1)r=",";if(i===true)i="#";else if(typeof i!=="string"||i.length!=1||i==r)i=false;this.parse=function(e){if(typeof e!=="string")throw"Input must be a string";j(e);return y()};this.abort=function(){g=true};this.getCharIndex=function(){return f}};
</script>

<!-- CSV strings to parse -->
<script>
var csvString = "a,b,c,d\,1,e,\N,f";



var csvStringSimple = "status,status_description,status_type\n100,Continue,Informational\n101,Switching Protocols,Informational\n200,OK,Successful\n201,Created,Successful\n202,Accepted,Successful\n203,Non-Authoritative Information,Successful\n204,No Content,Successful\n205,Reset Content,Successful\n206,Partial Content,Successful\n300,Multiple Choices,Redirection\n301,Moved Permanently,Redirection\n302,Found,Redirection\n303,See Other,Redirection\n304,Not Modified,Redirection\n305,Use Proxy,Redirection\n307,Temporary Redirect,Redirection\n400,Bad Request,Client Error\n401,Unauthorized,Client Error\n402,Payment Required,Client Error\n403,Forbidden,Client Error\n404,Not Found,Client Error\n405,Method Not Allowed,Client Error\n406,Not Acceptable,Client Error\n407,Proxy Authentication Required,Client Error\n408,Request Timeout,Client Error\n409,Conflict,Client Error\n410,Gone,Client Error\n411,Length Required,Client Error\n412,Precondition Failed,Client Error\n413,Request Entity Too Large,Client Error\n414,Request-URI Too Long,Client Error\n415,Unsupported Media Type,Client Error\n416,Requested Range Not Satisfiable,Client Error\n417,Expectation Failed,Client Error\n500,Internal Server Error,Server Error\n501,Not Implemented,Server Error\n502,Bad Gateway,Server Error\n503,Service Unavailable,Server Error\n504,Gateway Timeout,Server Error\n505,HTTP Version Not Supported,Server Error";
</script>

<!-- Prepare the parsers -->
<script>
var papa = new Papa.Parser();
var fastPapa = new Papa.Parser({ fastMode: true });
var oldPapa = new Papa3Parser();
var knrzCsv = new CSV(csvString);
</script>
    

Preparation code output

<!-- jQuery --> <!-- CSV libraries --> <script src="http://jquery-csv.googlecode.com/git/src/jquery.csv.js"></script> <script src="https://rawgit.com/henix/csv.js/master/csv.js"></script> <script>var henixCsv = CSV; // avoid namespace collision</script> <script src="https://rawgit.com/knrz/CSV.js/master/csv.min.js"></script> <script src="https://rawgit.com/mholt/PapaParse/master/papaparse.min.js"></script> <script> // Papa Parse 3.1 version of the parser function Papa3Parser(e){function y(){while(f<n.length){if(g)break;if(u>0&&m>=u)break;if(a=='"')E();else if(l)S();else x();b()}return w()}function b(){f++;a=n[f]}function w(){if(g)B("Abort","ParseAbort","Parsing was aborted by the user's step function");if(l)B("Quotes","MissingQuotes","Unescaped or mismatched quotes");A();if(!q(s))return I()}function E(){if(P()&&!D())l=!l;else{C();if(l&&D())f++;else B("Quotes","UnexpectedQuotes","Unexpected quotes")}}function S(){if(M(f)||_(f))c++;C()}function x(){if(a==r)k();else if(M(f)){L();b()}else if(_(f))L();else if(T())N();else C()}function T(){if(!i)return false;var e=f==0||_(f-1)||M(f-2);return e&&n[f]===i}function N(){while(!M(f)&&!_(f)&&f<n.length){b()}}function C(){h[d][v]+=a}function k(){h[d].push("");v=h[d].length-1}function L(){A();c++;m++;h.push([]);d=h.length-1;k()}function A(){O();if(q(s)){if(h[d])s(I());F()}}function O(){if(h[d].length==1&&t.test(h[d][0])){if(e.keepEmptyRows)h[d].splice(0,1);else h.splice(d,1);d=h.length-1}}function M(e){return e<n.length-1&&(n[e]=="\r"&&n[e+1]=="\n"||n[e]=="\n"&&n[e+1]=="\r")}function _(e){return n[e]=="\r"||n[e]=="\n"}function D(){return!P()&&f<n.length-1&&n[f+1]=='"'}function P(){return!l&&H(f-1)||H(f+1)}function H(e){if(typeof e!="number")e=f;var t=n[e];return e<=-1||e>=n.length||t==r||t=="\r"||t=="\n"}function B(e,t,n){p.push({type:e,code:t,message:n,line:c,row:d,index:f})}function j(e){n=e;l=false;f=0,m=0,c=1;F();h=[[""]];a=n[f]}function F(){h=[];p=[];d=0;v=0}function I(){return{data:h,errors:p,meta:{lines:c,delimiter:r,aborted:g,truncated:u>0&&f<n.length}}}function q(e){return typeof e==="function"}var t=/^\s*$/;var n;var r;var i;var s;var o;var u;var a;var f;var l;var c;var h;var p;var d;var v;var m;var g=false;e=e||{};r=e.delimiter;i=e.comments;s=e.step;u=e.preview;if(typeof r!=="string"||r.length!=1)r=",";if(i===true)i="#";else if(typeof i!=="string"||i.length!=1||i==r)i=false;this.parse=function(e){if(typeof e!=="string")throw"Input must be a string";j(e);return y()};this.abort=function(){g=true};this.getCharIndex=function(){return f}}; </script> <!-- CSV strings to parse --> <script> var csvString = "a,b,c,d\,1,e,\N,f"; var csvStringSimple = "status,status_description,status_type\n100,Continue,Informational\n101,Switching Protocols,Informational\n200,OK,Successful\n201,Created,Successful\n202,Accepted,Successful\n203,Non-Authoritative Information,Successful\n204,No Content,Successful\n205,Reset Content,Successful\n206,Partial Content,Successful\n300,Multiple Choices,Redirection\n301,Moved Permanently,Redirection\n302,Found,Redirection\n303,See Other,Redirection\n304,Not Modified,Redirection\n305,Use Proxy,Redirection\n307,Temporary Redirect,Redirection\n400,Bad Request,Client Error\n401,Unauthorized,Client Error\n402,Payment Required,Client Error\n403,Forbidden,Client Error\n404,Not Found,Client Error\n405,Method Not Allowed,Client Error\n406,Not Acceptable,Client Error\n407,Proxy Authentication Required,Client Error\n408,Request Timeout,Client Error\n409,Conflict,Client Error\n410,Gone,Client Error\n411,Length Required,Client Error\n412,Precondition Failed,Client Error\n413,Request Entity Too Large,Client Error\n414,Request-URI Too Long,Client Error\n415,Unsupported Media Type,Client Error\n416,Requested Range Not Satisfiable,Client Error\n417,Expectation Failed,Client Error\n500,Internal Server Error,Server Error\n501,Not Implemented,Server Error\n502,Bad Gateway,Server Error\n503,Service Unavailable,Server Error\n504,Gateway Timeout,Server Error\n505,HTTP Version Not Supported,Server Error"; </script> <!-- Prepare the parsers --> <script> var papa = new Papa.Parser(); var fastPapa = new Papa.Parser({ fastMode: true }); var oldPapa = new Papa3Parser(); var knrzCsv = new CSV(csvString); </script>

Test runner

Warning! For accurate results, please disable Firebug before running the tests. (Why?)

Java applet disabled.

Testing in CCBot 2.0.0 / Other 0.0.0
Test Ops/sec
jquery-csv
jQuery.csv.toArrays(csvString);
pending…
knrz/CSV.js
knrzCsv.parse();
pending…
henix/csv.js
henixCsv.parse(csvString);
pending…
Old Papa Parse (3.1)
oldPapa.parse(csvString);
pending…
Papa Parse
papa.parse(csvString);
pending…
henix/csv.js (no quoted fields)
henixCsv.parse(csvStringSimple);
pending…
Papa Parse (fast mode, no quoted fields)
fastPapa.parse(csvStringSimple);
pending…

Compare results of other browsers

Revisions

You can edit these tests or add even more tests to this page by appending /edit to the URL.

0 Comments