用C语言将一定数量的字符打印到标准输出的最快方法

用C语言将一定数量的字符打印到标准输出的最快方法,c,printing,stdout,C,Printing,Stdout,我必须打印一定数量的空格到标准输出,但这个数字不是固定的。我正在使用putchar(),但我不确定这是否很快。用C语言将一定数量的字符打印到标准输出的最快方法是什么?此外,我不能使用系统功能 谢谢你的帮助 printf()允许您调整要打印的空格数,但这必须在格式字符串中说明。以供参考 char format[256]; sprintf(format, "%%%ds", number_of_spaces); // creates the format string printf(format, "

我必须打印一定数量的空格到标准输出,但这个数字不是固定的。我正在使用putchar(),但我不确定这是否很快。用C语言将一定数量的字符打印到标准输出的最快方法是什么?此外,我不能使用系统功能

谢谢你的帮助

printf()
允许您调整要打印的空格数,但这必须在格式字符串中说明。以供参考

char format[256];
sprintf(format, "%%%ds", number_of_spaces); // creates the format string
printf(format, " ");
我假设“系统功能”是指非标准扩展。在这种情况下,这完全取决于您是指写得最快还是执行得最快

如果是前者,并且假设有一个上限,您可以使用如下内容:

void outSpaces (unsigned int num) {
    static char *lotsaSpaces = "                       ";
    printf ("%*.*s", num, num, lotsaSpaces);
}
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);
}
如果是后者,像这样的事情应该是一个很好的起点:

void outSpaces (unsigned int num) {
    static char *hundredSpaces = "<<insert 100 spaces here>>";
    while (num >= 100) {
        puts (hundredSpaces);
        num -= 100;
    }
    printf ("%*.*s", num, num, hundredSpaces);
}
void outSpaces(unsigned int num){
静态字符*hundredSpaces=“”;
而(数值>=100){
放置(百格);
num-=100;
}
printf(“%*.*s”,num,num,hundredSpaces);
}
您需要知道,函数调用可能非常昂贵,即使使用输出缓冲。在这种情况下,最好调用
put
一次以输出100个字符,而不是调用
putchar
100次。

也许:

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

我会尝试使用系统命令,而不是自己的命令

比如:

void outSpaces (unsigned int num) {
    static char *lotsaSpaces = "                       ";
    printf ("%*.*s", num, num, lotsaSpaces);
}
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);
}
就可以了。

#包括
#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;
}
#包括 #包括 #包括 int main(){ 常数大小=5; char*const data=(char*)malloc(size*sizeof(char)+1); 如果(!数据){ 返回退出失败; } memset(数据,,,大小); 数据[size]='\0';//不需要(在本例中) fwrite(数据,大小(字符),大小,标准输出); 免费(数据); 返回退出成功; }

(如果空格的数量不算太多)

我就用
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);
}
但是,请注意,naive版本也非常快:

void put_spaces(int n)
{
    while (n--)
        putchar(' ');
}
为什么这么快?在大多数系统上,
putchar
是一个宏,大部分时间直接写入缓冲区。如果您不确定它是否快速,正确的答案是评测您的应用程序,而不是“先优化”


远离
malloc
(这是不必要的),
put
(每次调用它时都会添加一个
'\n'
)和
printf
(对于这样一个简单的任务来说太复杂了)。

我不知道c,但这里是基本的想法。 创建一个大小为8192的数组,并用空格完全填充该数组,现在您可以使用puts或写入系统调用,或者使用一些有效的方法,然后打印该数组。 这里我有一个代码片段在围棋,但如果你喜欢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
主程序包
进口(
“布菲奥”
“操作系统”
)
func main(){
t:=[]字节{'y','\n'}
使用整型变量
常数tot=8192
buf:=make([]字节,0,总计)
用于
这(以及paxdiablo的)不取决于printf的实现吗?printf的padding一次循环一个字符吗?@Skizz,库函数的实现几乎总是比您期望的朴素C代码编译要聪明。这是因为它们经常被使用。@Skizz:不,printf的格式选项被定义为一个标准,不应该转移。正如paxdiablo在对我的回答的评论中提到的,printf仍然需要解析格式字符串。这很聪明,最后一点。但是我可能会选择
put
,因为它没有检查
%
格式说明符的开销。
put
函数会在末尾添加一个换行符。@Dietrich:oops,你说得很对。fputs不会写新行,所以您可以使用它-我的c std库已经生锈了!s/&spaces[19-num\u spaces]/spaces+19-num\u spaces/这里有很多有趣的答案。当然,你需要衡量每个人的表现才能知道正确的答案。但在现代操作系统中,它们之间可能没有什么联系,因为瓶颈是磁盘IO/控制台输出。
sizeof(char)
根据C规范,总是1。分配一个内存缓冲区,只是将数据复制到另一个内存缓冲区,似乎是相当浪费的……我只是想用
sizeof(char)
来表达我的意图。对于额外的缓冲区问题,
setbuf(stream,NULL)
可能会有所帮助。但不确定它是否在stdout上正常工作。对于实际文件的流,它应该可以工作,并且以二进制模式写入应该更有帮助。不,如果您调用
setbuf(stream,NULL)
我相当肯定,您将通过为每个stdio调用强制IO来破坏性能。明白。我对fwrite做了一些不好的假设。