问——为什么fwrite比普通快读(递归putchar)还慢???

P2249 【深基13.例1】查找

Joker_Error_404 @ 2023-12-07 18:41:37

我用fread和fwrite 600+ ms

但是用fread和递归putchar 却是88ms

不应该putchar比fwrite慢吗?

那有1e5个输出啊!!!


by Bingxiu @ 2023-12-07 19:04:09

@Joker_Error_404 代码?


by Joker_Error_404 @ 2023-12-07 20:33:25

fwrite:

#include<algorithm>
#include<iostream>
using namespace std;
char B_u_f[1<<14],*p_1=B_u_f,*p_2=B_u_f;
inline char _read_()
{
    return (p_1==p_2&&(p_2=(p_1=B_u_f)+fread(B_u_f,1,1<<14,stdin),p_1==p_2))?EOF:*p_1++;
}
/*inline void input(char &a)
{
    a=_read_();
}*/
inline void input(int &a)
{
    char b=1;
    a=0;
    char c=_read_();
    while(!isdigit(c))
    {
        if(c=='-')b=-1;
        c=_read_();
    }
    while(isdigit(c))
    {
        a=a*10+c-48;
        c=_read_();
    }
    a*=b;
    return;
}
char b_u_f[1<<14];
int p_3=0,p_4=1<<14;
inline void _write_()
{
    fwrite(b_u_f,1,p_3,stdout);
    p_3=0;
    return;
}
inline void print(int a)
{
    if(a<0)
    {
        b_u_f[p_3++]='-',a=-a;
        if(p_3==p_4)_write_();
    }
    else if(a==0)
    {
        b_u_f[p_3++]=48;
        if(p_3==p_4)_write_();
    }
    char c[99999]={0};
    int i=0;
    while(a)
    {
        c[i++]=a%10+48;
        a/=10;
    }
    while(i)
    {
        b_u_f[p_3++]=c[--i];
        if(p_3==p_4)_write_();      
    }
}
/*inline void print(const char c)
{
    *p_3++=c;
    if(p_3==p_4)_write_();
}*/
//------------------------------------
int main()
{
    int n,m;
    int a[1000000]={0};
    input(n);
    input(m);
    int x;
    for(int q=0;q<n;q++)input(a[q]);
    for(int q=0;q<m;q++)
    {
        input(x);
        int ar=lower_bound(a,a+n,x)-a;
        if(a[ar]==x)print(ar+1);
        else print(-1);
        b_u_f[p_3++]=32;
        if(p_3==p_4)_write_();
    }
    _write_();
    return 0;
}

putchar:

#include<algorithm>
#include<iostream>
using namespace std;
char B_u_f[1<<14],*p_1=B_u_f,*p_2=B_u_f;
inline char _read_()
{
    return (p_1==p_2&&(p_2=(p_1=B_u_f)+fread(B_u_f,1,1<<14,stdin),p_1==p_2))?EOF:*p_1++;
}
/*inline void input(char &a)
{
    a=_read_();
}*/
inline void input(int &a)
{
    char b=1;
    a=0;
    char c=_read_();
    while(!isdigit(c))
    {
        if(c=='-')b=-1;
        c=_read_();
    }
    while(isdigit(c))
    {
        a=a*10+c-48;
        c=_read_();
    }
    a*=b;
    return;
}
//char b_u_f[1<<23|1],*p_3=b_u_f,*p_4=&b_u_f[1<<23];
//inline void _write_()
//{
//  fwrite(b_u_f,1,p_3-b_u_f,stdout);
//  p_3=b_u_f;
//  return;
//}
inline void print(int a)
{
    if(a<0)putchar('-'),a=-a;
    if(a>=10)print(a/10);
    putchar(a%10+48);
}
/*inline void print(const char c)
{
    *p_3++=c;
    if(p_3==p_4)_write_();
}*/
//------------------------------------
int main()
{
    int n,m;
    int a[1000000]={0};
    input(n);
    input(m);
    int x;
    for(int q=0;q<n;q++)input(a[q]);
    for(int q=0;q<m;q++)
    {
        input(x);
        int ar=lower_bound(a,a+n,x)-a;
        if(a[ar]==x)print(ar+1);
        else print(-1);
        putchar(' ');
    }
    return 0;
}

by Joker_Error_404 @ 2023-12-07 20:34:51

@Bingxiu

这个快读为了不和其他变量冲突,变量都改的很奇怪……


by Bingxiu @ 2023-12-07 20:52:32

@Joker_Error_404 你这,把快读快写的坑全踩了一遍

  1. 一定不要把快读快写的数组大小开成 2 的幂次,最好是 2^k+1,也就是把数组大小 +1
  2. 输入字符的操作不要写函数,写成 define 会快很多,因为函数调用需要消耗一定的时间,但是宏替换会在编译期做好工作
  3. char c[99999]={0} 这种方式会消耗很多时间初始化,因为每一次调用函数都要重新初始化一个数组,最好开全局的数组或者使用 static char c[99999]={0}
  4. 大数组不要用大括号内嵌列表初始化,否则编译器会直接把编译出来的初始化写成类似 c[0]=0;c[1]=0;c[2]=0;c[3]=0;......;c[99998]=0;,如果真的要这么干,请使用 memset,fill,iotafor 循环

by Joker_Error_404 @ 2023-12-08 13:28:39

@Bingxiu

阿哲…………

我改改


by Joker_Error_404 @ 2023-12-08 13:49:08

@Bingxiu 谢谢大佬

我把c[9999]={0}改成了

c[9999]

然后就好了(82ms)

其他的函数和宏定义好像差不多……

现在才知道大数组怎么搞会那么慢

谢谢


|