ทำไมเขียนโปรแกรมโดยใช้การ คูณ ถึงดีกว่าการ หาร ครับ

อ้างอิงการเขียนโปรแกรมตามภาษา C ครับ

ตามปกติ
DATA_AVG = ( A[0] + ...... A[5] ) / 6

แต่ผมดู code ของหลายคนเลือกที่จะเขียนแบบนี้
DATA_AVG = ( A[0] + ...... A[5] ) * 0.16667

เป็นเพราะเหตุใด ขอบคุณครับ

คำตอบที่ได้รับเลือกจากเจ้าของกระทู้
ความคิดเห็นที่ 12
benchmark มาแล้วครับ


#include <stdio.h>
#include <time.h>

int main()
{
   int i;
   double a[6];
   time_t st;

#define AVG1   a[0] = (a[0]+a[1]+a[2]+a[3]+a[4]+a[5]) / 6;
#define AVG2   a[0] = (a[0]+a[1]+a[2]+a[3]+a[4]+a[5]) * 0.16667;

   for (i=0; i<6; ++i)
      a[i]=i;
   st=time(NULL);
   for (i=0; i<10000000; ++i)
   {
      AVG1 AVG1 AVG1 AVG1 AVG1 AVG1 AVG1 AVG1 AVG1 AVG1
      AVG1 AVG1 AVG1 AVG1 AVG1 AVG1 AVG1 AVG1 AVG1 AVG1
      AVG1 AVG1 AVG1 AVG1 AVG1 AVG1 AVG1 AVG1 AVG1 AVG1
      AVG1 AVG1 AVG1 AVG1 AVG1 AVG1 AVG1 AVG1 AVG1 AVG1
      AVG1 AVG1 AVG1 AVG1 AVG1 AVG1 AVG1 AVG1 AVG1 AVG1
      AVG1 AVG1 AVG1 AVG1 AVG1 AVG1 AVG1 AVG1 AVG1 AVG1
      AVG1 AVG1 AVG1 AVG1 AVG1 AVG1 AVG1 AVG1 AVG1 AVG1
      AVG1 AVG1 AVG1 AVG1 AVG1 AVG1 AVG1 AVG1 AVG1 AVG1
      AVG1 AVG1 AVG1 AVG1 AVG1 AVG1 AVG1 AVG1 AVG1 AVG1
      AVG1 AVG1 AVG1 AVG1 AVG1 AVG1 AVG1 AVG1 AVG1 AVG1
   }
   printf("AVG1 use %ld sec\n",time(NULL)-st);

   for (i=0; i<6; ++i)
      a[i]=i;
   st=time(NULL);
   for (i=0; i<10000000; ++i)
   {
      AVG2 AVG2 AVG2 AVG2 AVG2 AVG2 AVG2 AVG2 AVG2 AVG2
      AVG2 AVG2 AVG2 AVG2 AVG2 AVG2 AVG2 AVG2 AVG2 AVG2
      AVG2 AVG2 AVG2 AVG2 AVG2 AVG2 AVG2 AVG2 AVG2 AVG2
      AVG2 AVG2 AVG2 AVG2 AVG2 AVG2 AVG2 AVG2 AVG2 AVG2
      AVG2 AVG2 AVG2 AVG2 AVG2 AVG2 AVG2 AVG2 AVG2 AVG2
      AVG2 AVG2 AVG2 AVG2 AVG2 AVG2 AVG2 AVG2 AVG2 AVG2
      AVG2 AVG2 AVG2 AVG2 AVG2 AVG2 AVG2 AVG2 AVG2 AVG2
      AVG2 AVG2 AVG2 AVG2 AVG2 AVG2 AVG2 AVG2 AVG2 AVG2
      AVG2 AVG2 AVG2 AVG2 AVG2 AVG2 AVG2 AVG2 AVG2 AVG2
      AVG2 AVG2 AVG2 AVG2 AVG2 AVG2 AVG2 AVG2 AVG2 AVG2
   }
   printf("AVG2 use %ld sec\n",time(NULL)-st);

   return 0;
}



code หาค่าเฉลี่ยอยู่ตรงนี้


#define AVG1   a[0] = (a[0]+a[1]+a[2]+a[3]+a[4]+a[5]) / 6;
#define AVG2   a[0] = (a[0]+a[1]+a[2]+a[3]+a[4]+a[5]) * 0.16667;


ผมแก้นิดหน่อย โดยให้ผลลัพธ์กลับไปใส่ที่ a[0]
เพื่อป้องกัน compiler คิดว่าไม่มีการแก้ไขค่าของ variable
มันอาจ optimize โดยทำ AVG แค่ครั้งเดียว หรืออาจไม่ทำเลย
จับเวลาการทำ AVG โดย for loop สิบล้านรอบ แต่ละรอบทำร้อยครั้ง
รวมเป็นพันล้านครั้ง
ที่ต้องทำรอบละร้อยครั้งเพื่อลดผลของ for loop

ทดสอบบน linux server ไม่ทราบ spec
รอบแรก compile แบบ optimize
แล้วรันสองครั้ง
นี่คือผลลัพธ์

gcc -O -o bm bm.c
./bm
AVG1 use 23 sec
AVG2 use 9 sec
./bm
AVG1 use 23 sec
AVG2 use 9 sec



รอบถัดมา compile แบบไม่กำหนด optimize

gcc -o bm bm.c
./bm
AVG1 use 25 sec
AVG2 use 12 sec
./bm
AVG1 use 25 sec
AVG2 use 11 sec



เห็นได้ว่า การหาร ช้ากว่า การคูณ มากกว่าสองเท่า





;>)

แสดงความคิดเห็น
โปรดศึกษาและยอมรับนโยบายข้อมูลส่วนบุคคลก่อนเริ่มใช้งาน อ่านเพิ่มเติมได้ที่นี่