This really bugged me so I used the opportunity to learn a bit more about LibraryLink. I have to say that have a close look at Szabolcs' LTemplate package was significantly more helpful than the actual LibraryLink documentation...

Setting up the C++ code:

    Needs["CCompilerDriver`"];
    Needs["GeneralUtilities`"];
    
    LibraryLink`BoilerPlate[funname_String] := 
     StringJoin["#include \"math.h\"
      
      #include \"WolframRTL.h\"
      
      static WolframCompileLibrary_Functions funStructCompile;
      
      static mbool initialize = 1;
      
      DLLEXPORT int Initialize_", funname, "(WolframLibraryData libData)
      {
      	if( initialize)
      	{
      		funStructCompile = libData->compileLibraryFunctions;
      		initialize = 0;
      	}
      	return 0;
      }
      
      DLLEXPORT void Uninitialize_", funname, "(WolframLibraryData libData)
      {
      	if( !initialize)
      	{
      		initialize = 1;
      	}
      }
      
      "]
    
    
    funname = "writeRealMatrixToFile";
    preamble = "
      #include <iostream>
      #include <fstream>
      using namespace std;
      ";
    
    code = StringJoin[
       preamble, "\n\n",
       LibraryLink`BoilerPlate[funname],
       "extern \"C\" DLLEXPORT int ", funname, 
       "(WolframLibraryData libData, mint Argc, MArgument * Args, \
    MArgument Res)
       {
       	int err = 0;
           const char * file = MArgument_getUTF8String(Args[0]);
           const MTensor a0 = MArgument_getMTensor(Args[1]);
       	   const mreal * a = libData->MTensor_getRealData(a0);
           const char * prefix = MArgument_getUTF8String(Args[2]);
           const char * infix = MArgument_getUTF8String(Args[3]); 
           const char * suffix = MArgument_getUTF8String(Args[4]);
           const char * linesep = MArgument_getUTF8String(Args[5]);
           mint prec = MArgument_getInteger(Args[6]);
       	
       	   mint const* dims;
           dims = libData->MTensor_getDimensions(a0);
       	mint i, j;
       
       	ofstream outputstream;
       
       	try
       	{
       		outputstream.open(file, ofstream::out | ofstream::app);
       		outputstream.precision(prec);
       		outputstream.setf(ios::fixed, ios::floatfield);
       
       		for( i=0; i < (dims[0]-1); i++)
       		{
       			outputstream << prefix;
       			for( j=0; j < dims[1]-1; j++)
       			{
       				outputstream << *a << infix; 
       				a++;
       			}
       			outputstream << *a << suffix;
       			a++;
       			outputstream << linesep;
       		}
       		{
       			outputstream << prefix;
       			for( j=0; j < dims[1]-1; j++)
       			{
       				outputstream << *a << infix;
       				a++;
       			}
       			outputstream << *a << suffix;
       		}
               
       		outputstream.close();
       		MArgument_setInteger(Res, err);
       	}
       	catch (...)
       	{
       		return LIBRARY_FUNCTION_ERROR;
       	}
       
       	return LIBRARY_NO_ERROR;
       }
       "];

Creating the library in a temporary directory. (If you'd like to reuse the library, just specify a value of choice for `"TargetDirectory"`.)

    libfile = CreateLibrary[
       code, funname,
       "Language" -> "C++",
       "TargetDirectory" -> $TemporaryDirectory
       ];

Loading the library function and creating a wrapper function as rudimentary user interface.

    If[TrueQ[Head[writeRealMatrixToFile] === LibraryFunction], 
      LibraryFunctionUnload[writeRealMatrixToFile]];
    ClearAll[writeRealMatrixToFile];
    If[TrueQ[FindLibrary[libfile] =!= $Failed],
      writeRealMatrixToFile = LibraryFunctionLoad[libfile, funname,
        {
         "UTF8String", {Real, 2, "Constant"}, "UTF8String", "UTF8String", 
         "UTF8String", "UTF8String", Integer
         },
        Integer]
      ];
    
    Options[WriteRealMatrixToFile] = {
       "Prefix" -> "",
       "Infix" -> "\t",
       "Suffix" -> "",
       "RowSep" -> "\n",
       "Precision" -> 16
       };
    WriteRealMatrixToFile[file_String, 
       A_?(MatrixQ[#, Developer`MachineRealQ] &), OptionsPattern[]] := 
      writeRealMatrixToFile[file, A,
       OptionValue["Prefix"],
       OptionValue["Infix"],
       OptionValue["Suffix"],
       OptionValue["RowSep"],
       OptionValue["Precision"]
       ];

Running the test example.

    A = RandomReal[{-1, 1}, {1000, 1000}];
    file = "test.txt";
    Put[file];
    WriteRealMatrixToFile[file, A]; // AbsoluteTiming // First
    B = Import[file, "Table"]; // AbsoluteTiming // First
    Max[Abs[A - B]]

> 0.618298
> 
> 1.40147
> 
> 5.55112*10^-17

This is almost 25 times faster than using `Export` with `"Table"` as export format:

    Export["A.txt", A, "Table"]; // AbsoluteTiming // First

> 16.0703