Voltage meter ADC + serial: Bytes lost during communication
With help in a comments I've managed to deal with the task myself. 

First of all, as @Majenko pointed out, I was dealing with some multi-byte data. So I need some control character, that separates packets. I choose hex output with '\n' delimeter as control character - that served good. I was able to read 3.5 to 5k packets per second (with voltage reading) from serial on the host.

Second improvement, credited to @Jot, is to stack some sequential values right in arduino, before sending. 

Alongside with increasing sampler frequency that could be very good.

#define cbi(sfr, bit) (_SFR_BYTE(sfr) &amp;= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

void setup() {
  sbi(ADCSRA, ADPS2);
  cbi(ADCSRA, ADPS1);
  cbi(ADCSRA, ADPS0);
  Serial.begin(115200);
}

void loop() {
  int val = 0;
  for( int i = 0; i &lt; 32; ++i )
    val += analogRead(A0); 
  Serial.print(val, HEX);
  Serial.print("\n");
}


at the host recieve side, some simple conversion could be done:

#include "Serial.h"
#include &lt;iostream&gt;
#include &lt;fstream&gt;
#include &lt;string&gt;
#include &lt;ctime&gt;

// sample to voltage
double s2v(int sample) {
    return 5.0 * (static_cast&lt;double&gt;(sample) / 1024);
}

int main() {
    std::ofstream ofs("test.csv", std::ios::out | std::ios::ate);

    size_t comPort = 3;
    size_t baudRate = 115200; // 57600;

    CSerial serial;
    if (serial.Open(comPort, baudRate))
    {
        std::cout &lt;&lt; "COM" &lt;&lt; comPort &lt;&lt; " opened @" &lt;&lt; baudRate &lt;&lt; "bit/s\n";

        // serial recv buffer 
        size_t bufSize = 1048576;
        auto lpBuffer = new char[bufSize];

        // accumulator
        size_t nVals = 0;
        int nAcc = 0;

        // timer
        __time64_t destTime;
        __time64_t destTime2;
        _time64(&amp;destTime);

        while (true) {
            SleepEx(10, false); // care of 100% cpu core usage, poll serial port lazily
            size_t nBytesRead = serial.ReadData(lpBuffer, bufSize * sizeof(lpBuffer[0]));

            //parse buffer:
            size_t cvtPtr = 0;
            for (size_t i = 0; i &lt; nBytesRead; ++i) {
                if (lpBuffer[i] == '\n') {
                    try {
                        lpBuffer[i] = '\0';
                        auto val = std::stoi(lpBuffer + cvtPtr, nullptr, 16);
                        nAcc += val;
                        nVals++;
                    }
                    catch (...) {
                        // ignore, or warn that serial recieved junk/empty packet
                    }
                    cvtPtr = i + 1;
                }
            }

            //check if doom had come!
            _time64(&amp;destTime2);
            if ((destTime2 - destTime) &gt; 0) {
                auto fVoltage = ( s2v(nAcc) / 32 ) / nVals;
                std::cout &lt;&lt; fVoltage &lt;&lt; "\t(" &lt;&lt; nVals &lt;&lt; " ksps)\n";
                ofs &lt;&lt; destTime &lt;&lt; "," &lt;&lt; fVoltage &lt;&lt; "," &lt;&lt; nVals &lt;&lt; "\n";
                if((destTime % 30 ) == 0) // care of disk, write only once in 30 seconds
                    ofs.flush();
                destTime = destTime2;
                nVals = 0;
                nAcc = 0;
            }
        } // while
    } // if opened
    return 0;
}


That gives voltmeter with high precision, about ±0.5mV, that is updated every second.

Also! It was stated about 10bit adc, 5.0V/1024 = 4.88mV, but i got some subthreshold oscillations in vivo, adding samples up. So you are wrong, noise can be attenuated and resolution can be artificially pumbed up, in a trade for increased sampling time. Here is 14bit ADC built on top of 10bit ADC: . Its photovoltaic cell in a dark street, oscillations are caused by cars' front lights. Timescale is 1000 seconds per grid div