Tianyang Li
Tianyang Li

Reputation: 1785

Fastest way to print a certain number of characters to stdout in C

I have to print a certain number of blank spaces to stdout, but this number is not fixed. I'm using putchar(), but I'm not sure if this is fast. What is the fastest way to print a certain number of characters to stdout in C? Also, I cannot use system functions.

Thanks for you help!

Upvotes: 5

Views: 8015

Answers (7)

nilsocket
nilsocket

Reputation: 1571

I don't known c, but here is the basic idea. create an array of size 8192, and completely fill that particular array with spaces, now you can use puts or write system call or use something which is efficient, and then print this array. Here I have a code snippet in go, but if you prefer c, you can see an example of how you do it, its actually GNU's yes program which is freaking fast at printing things, there is followed up explanation over there.

package main

import (
    "bufio"
    "os"
)

func main() {
    t := []byte{'y', '\n'}
    var used int
    const tot = 8192
    buf := make([]byte, 0, tot)

    for used < tot {
        buf = append(buf, t...)
        used += 2
    }

    //Filled complete array named as buf with "y\n"
    w := bufio.NewWriter(os.Stdout)
    for {
        w.Write(buf) //using write system call to print.
    }
    w.Flush()
}

//syscall.Write({without buf}) : 1.40MiB/s
//syscall.Write(buf) : 1.5GiB/s

Upvotes: 0

Dietrich Epp
Dietrich Epp

Reputation: 213558

I would just use fwrite. Simple. Correct. Easy.

void put_spaces(int n)
{
    static const char SPACES[32] = "                                ";
    for (; n >= 32; n -= 32)
        fwrite(SPACES, 32, 1, stdout);
    if (n)
        fwrite(SPACES, n, 1, stdout);
}

Note, however, that the naive version is also quite fast:

void put_spaces(int n)
{
    while (n--)
        putchar(' ');
}

Why is it fast? On most systems, putchar is a macro which writes directly into a buffer most of the time. If you're not sure it's fast, the correct answer is profile your application, not "optimize first".

Stay away from malloc (it's just unnecessary), puts (which adds a '\n' every time you call it), and printf (it's too complicated for such a simple task).

Upvotes: 4

Shadow2531
Shadow2531

Reputation: 12170

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>

int main() {
    const size_t size = 5;
    char* const data = (char*)malloc(size * sizeof(char) + 1);
    if (!data) {
        return EXIT_FAILURE;
    }
    memset(data, ' ', size);
    data[size] = '\0'; // not needed (in this case)
    fwrite(data, sizeof(char), size, stdout);
    free(data);
    return EXIT_SUCCESS;
}

(If the number of spaces isn't outrageous)

Upvotes: 0

Martin Kristiansen
Martin Kristiansen

Reputation: 10222

I would try to use the system commands instead of making my own.

something like:

void print_spaces(unsigned int number_of_spaces) {
  char* spaces = malloc(sizeof(char)*number_of_spaces + 1);
  memset (spaces,' ',number_of_spaces);
  spaces[number_of_spaces] = '\0';
  printf("%s",spaces);
  free(spaces);
}

would do the trick.

Upvotes: 1

Skizz
Skizz

Reputation: 71090

Perhaps:

void PrintSpaces (int num_spaces)
{
  char *spaces = "                    "; /* twenty spaces */
  while (num_spaces > 20)
  {
    puts (spaces);
    num_spaces -= 20;
  }

  if (num_spaces)
  {
    puts (&spaces [19 - num_spaces]);
  }
}

Upvotes: 0

paxdiablo
paxdiablo

Reputation: 882028

I'm assuming by "system functions", you mean non-standard extensions. In which case, it all depends on whether you mean fastest to write or fastest to execute?

If the former, and assuming there's an upper limit, you can just use something like:

void outSpaces (unsigned int num) {
    static char *lotsaSpaces = "                       ";
    printf ("%*.*s", num, num, lotsaSpaces);
}

If the latter, something like this should be a good starting point:

void outSpaces (unsigned int num) {
    static char *hundredSpaces = "<<insert 100 spaces here>>";
    while (num >= 100) {
        puts (hundredSpaces);
        num -= 100;
    }
    printf ("%*.*s", num, num, hundredSpaces);
}

You need to be aware that function calls can be expensive, even with output buffering. In that case, it may be best to call puts once to output a hundred characters rather than call putchar a hundred times.

Upvotes: 0

Constantinius
Constantinius

Reputation: 35069

printf() allows you to adjust the number of spaces to be print, but this has to be stated in the format string. Se here for reference.

char format[256];
sprintf(format, "%%%ds", number_of_spaces); // creates the format string
printf(format, " ");

Upvotes: 0

Related Questions