After using them for several years, I have to admit that many `Export` routines in Mathematica are either broken or _way_ too slow (a factor of 10 to 25 when compared to a "C++" routine, e.g. for such a simple task as exporting an array). It is very unfortunate. However, the following can export the data within 1.6 seconds while the OP's version took 15.985 seconds on my machine. It allows for specifying how many digits have to be exported. colsep = "\t"; rowsep = "\n"; prec = 16; SetAttributes[doubletostring, Listable]; doubletostring[x_] := Internal`DoubleToString[x, False, prec]; Export[ "a.txt", StringJoin[ Map[ row \[Function] StringJoin[Riffle[doubletostring /@ row, colsep], rowsep], e] ] ]; // AbsoluteTiming // First > 1.60592 This timing is from Mathematica 11.3 on macOS v10.13.4 (High Sierra). [A hand-written C++ routine linked to Mathematica](https://mathematica.stackexchange.com/a/171587/38178) needs about 0.6 seconds to export the matrix `e`, so in principle, there is still room for improvement. <s>Since ``Internal`DoubleToString`` is undocumented, I have no idea what its second argument does (it appears to me that it has no effect which would be pretty weird).</s> As [ilian][5] told me in [this post][6], the second argument controls whether `NumberMark` shall be printed (`False` suppresses it). The third argument seems to specify how many leading digits have to be printed. Some further speedup can be obtained by using `ParallelMap` instead of `Map`. Once the parallel kernels are set up and started, the timing is pretty close to the (unparallelized) C++ timing on my Quad Core machine: Export["a.txt", StringJoin[ ParallelMap[ row \[Function] StringJoin[Riffle[doubletostring@row, colsep], rowsep], e ] ] ]; // AbsoluteTiming // First > 0.875412 [5]: https://mathematica.stackexchange.com/users/145 [6]: https://mathematica.stackexchange.com/a/170907/38178