开发者

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!


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).


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.


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, " ");


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.


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]);
  }
}


#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)


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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜