用C语言将一定数量的字符打印到标准输出的最快方法
我必须打印一定数量的空格到标准输出,但这个数字不是固定的。我正在使用putchar(),但我不确定这是否很快。用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, "
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做了一些不好的假设。