Самый быстрый способ напечатать определенное количество символов на стандартный вывод в C - PullRequest
3 голосов
/ 12 мая 2011

Я должен напечатать определенное количество пробелов в стандартный вывод, но это число не является фиксированным.Я использую putchar (), но я не уверен, что это быстро.Какой самый быстрый способ напечатать определенное количество символов на стандартный вывод в C?Также я не могу использовать системные функции.

Спасибо за помощь!

Ответы [ 7 ]

3 голосов
/ 12 мая 2011

Я бы просто использовал fwrite.Просто.Правильный.Легко.

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

Обратите внимание, однако, что наивная версия также довольно быстрая:

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

Почему это быстро?В большинстве систем putchar - это макрос, который большую часть времени пишет непосредственно в буфер.Если вы не уверены, что это быстро, правильный ответ - профилируйте ваше приложение, не "оптимизируйте первым".

Держитесь подальше от malloc (это просто не нужно), puts(который добавляет '\n' при каждом вызове) и printf (это слишком сложно для такой простой задачи).

0 голосов
/ 23 октября 2017

Я не знаю, с, но вот основная идея.создайте массив размером 8192 и полностью заполните этот конкретный массив пробелами, теперь вы можете использовать put или write системный вызов или использовать что-то эффективное, а затем распечатать этот массив.Здесь у меня есть фрагмент кода в go, но если вы предпочитаете c, вы можете увидеть пример того, как вы это делаете, на самом деле это программа GNU yes, которая быстро печатает, есть объяснениетам.

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 голосов
/ 12 мая 2011
#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;
}

(Если количество пробелов не возмутительно)

0 голосов
/ 12 мая 2011

Я бы попытался использовать системные команды вместо того, чтобы делать свои собственные.

что-то вроде:

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

сделает свое дело.

0 голосов
/ 12 мая 2011

Возможно:

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]);
  }
}
0 голосов
/ 12 мая 2011

Я предполагаю, что под "системными функциями" вы подразумеваете нестандартные расширения. В этом случае все зависит от того, имеете ли вы в виду быстрее всего писать или быстрее всего выполнять?

Если первое и предполагается, что есть верхний предел, вы можете просто использовать что-то вроде:

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

Если последнее, что-то вроде этого должно быть хорошей отправной точкой:

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

Вы должны знать, что вызовы функций могут быть дорогими, даже с буферизацией вывода. В этом случае лучше всего один раз вызвать puts, чтобы вывести сто символов, а не сто раз putchar.

0 голосов
/ 12 мая 2011

printf() позволяет настроить количество пробелов для печати, но это должно быть указано в строке формата.Se здесь для справки.

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