While more elaborate interrupt- or DMA-based code would be necessary to achieve the best performance, relatively minor improvements to your code would improve the situation already. I'd start by transmitting samples in binary instead of in text. This requires slightly more work at the receiving end, but will cut the required UART bandwidth by at least 2-3x (2 bytes per sample vs. up to 6 in text with separator). You can also readily increase the baud rate to, e.g., 921.6kbps, which is standard and should be well supported on the receiving end. Assuming a standard STM32F2 architecture, you could go up to 7.5Mbps but you'd need to check support for that at the receiving end.
With 2 bytes per sample and 921.6kbps, you would get a throughput of about 46'000 samples/s. At 7.5Mbps, you'd get 370'000 samples/s. If your application allows it, you could reduce the resolution to 8 bits and thus use a single byte per sample, effectively doubling the throughput in samples/s.
While 370ksamples/s is not bad, it's still pretty far from the theoretical 6Msamples/s (assuming STM32F2, 12bit conversion and using the 3 ADC in triple interleaved mode). This translates to 12MB/s of data to transfer from the MCU to the computer, which is no trivial amount. UART will not do. SPI, at a max of 30Mbps (2-3MB/s) wont do it either. Writing to a microSD card via SDIO would come close. USB 2.0 would do it but is much more complicated software-wise and requires external components for the PHY. ETH would do fine as well but would require additional components and a network stack to be implemented on the MCU. This complexity explains why, in most applications, the samples are buffered in memory and transferred asynchronously.