เนื่องจากไม่มีใครพูดถึงฉันจึงเพิ่มหมายเหตุเกี่ยวกับการแสดงของพวกเขา
ภายใต้สถานการณ์ปกติโดยสมมติว่าไม่มีการใช้การเพิ่มประสิทธิภาพคอมไพเลอร์ (เช่นprintf()เรียกจริงprintf()ไม่ใช่fputs()) ฉันคาดว่าprintf()จะทำงานได้อย่างมีประสิทธิภาพน้อยลงโดยเฉพาะอย่างยิ่งสำหรับสตริงที่ยาว เนื่องจากprintf()ต้องแยกวิเคราะห์สตริงเพื่อตรวจสอบว่ามีตัวระบุการแปลงหรือไม่
เพื่อยืนยันสิ่งนี้ฉันได้ทำการทดสอบบางอย่าง การทดสอบดำเนินการบน Ubuntu 14.04 พร้อม gcc 4.8.4 เครื่องของฉันใช้ซีพียู Intel i5 โปรแกรมที่กำลังทดสอบมีดังนี้:
#include <stdio.h>
int main() {
int count = 10000000;
while(count--) {
// either
printf("qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM");
// or
fputs("qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM", stdout);
}
fflush(stdout);
return 0;
}
ทั้งสองรวบรวมด้วยgcc -Wall -O0. เวลาวัดโดยใช้time ./a.out > /dev/null. ต่อไปนี้เป็นผลลัพธ์ของการวิ่งโดยทั่วไป (ฉันเรียกใช้ห้าครั้งผลลัพธ์ทั้งหมดอยู่ภายใน 0.002 วินาที)
สำหรับprintf()ตัวแปร:
real 0m0.416s
user 0m0.384s
sys 0m0.033s
สำหรับfputs()ตัวแปร:
real 0m0.297s
user 0m0.265s
sys 0m0.032s
เอฟเฟกต์นี้จะถูกขยายหากคุณมีสตริงที่ยาวมาก
#include <stdio.h>
#define STR "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM"
#define STR2 STR STR
#define STR4 STR2 STR2
#define STR8 STR4 STR4
#define STR16 STR8 STR8
#define STR32 STR16 STR16
#define STR64 STR32 STR32
#define STR128 STR64 STR64
#define STR256 STR128 STR128
#define STR512 STR256 STR256
#define STR1024 STR512 STR512
int main() {
int count = 10000000;
while(count--) {
// either
printf(STR1024);
// or
fputs(STR1024, stdout);
}
fflush(stdout);
return 0;
}
สำหรับprintf()ตัวแปร (วิ่งสามครั้งบวกจริง / ลบ 1.5 วินาที):
real 0m39.259s
user 0m34.445s
sys 0m4.839s
สำหรับfputs()ตัวแปร (วิ่งสามครั้งบวกจริง / ลบ 0.2 วินาที):
real 0m12.726s
user 0m8.152s
sys 0m4.581s
หมายเหตุ:หลังจากการตรวจสอบที่เกิดการชุมนุมโดย GCC ฉันตระหนัก GCC ที่เพิ่มประสิทธิภาพfputs()การโทรไปยังโทรแม้จะมีfwrite() -O0(การprintf()เรียกยังคงไม่เปลี่ยนแปลง) ฉันไม่แน่ใจว่าสิ่งนี้จะทำให้การทดสอบของฉันเป็นโมฆะหรือไม่เนื่องจากคอมไพลเลอร์คำนวณความยาวสตริงสำหรับfwrite()เวลาคอมไพล์
printf("Hello World!")เป็นไม่ได้puts("Hello World!")เช่นเดียวกับputs()ผนวกก'\n'. แทนที่จะเปรียบเทียบprintf("abc")กับfputs("abc", stdout)