Đo thời gian thực hiện chương trình C/C++/C# (Timer 4 newbie)

Đo thời gian thực hiện chương trình C/C++/C# (Timer 4 newbie)

Ngày 10/03/2014: Cập nhật với chuẩn C++11, xem bài viết tại đây (lưu ý phần đo thời gian với thư viện chrono ở trang 2 của bài báo).
(Ngày cập nhật cuối: 30/3/2009)
Chủ đề bài báo: C/C++/C#
Trong các cuộc thi lập trình, các chương trình cài đặt các thuật toán cùng giải quyết một bài toán, chúng ta luôn có nhu cầu kiểm thử tốc độ thực hiện của các cài đặt bằng cách xem xét thời gian một đoạn chương trình hay một chương trình thực hiện là bao lâu. Trong bài báo nhỏ này, tôi xin cung cấp cách thức đo thời gian thực hiện của các chương trình được viết bằng các ngôn ngữ C/C++/C# trên DOS và trên Windows.
1. Đo thời gian thực hiện chương trình với ngôn ngữ C/C++ trên DOS
Đối với môi trường DOS chúng ta có thể dùng hàm clock() để đo thời gian thực hiện của chương trình cho cả chương trình viết bằng C và C++. Hàm clock() có khai báo nằm trong file header time.h, giá trị trả về của hàm là thời gian bắt đầu từ lúc chương trình chạy cho tới lúc gọi hàm, tính bằng số giây nhân với hằng số CLOCKS_PER_SEC, hằng số CLOCKS_PER_SEC có giá trị như CLK_TCK.
Ví dụ sau đo thời gian thực hiện của 600000000 vòng lặp rỗng:
// file timer4c.c
#include
#include
#include
int main( void )
{
long i = 600000000L;
clock_t start, finish;
double duration;
// Do thoi gian cua mot su kien
printf( “Thoi gian thuc hien %ld vong lap rong:”, i );
start = clock();
while( i– )
;
finish = clock();
duration = (double)(finish – start) / CLOCKS_PER_SEC;
printf( “%2.1f giay\n”, duration );
system(“pause”);
return 0;
}
2. Đo thời gian thực hiện chương trình với ngôn ngữ C trên Windows
Trên Windows chúng ta sử dụng hàm QueryPerformanceCounter(LARGE_INTEGER *) để thực hiện việc đo thời gian, hàm được khai báo trong file header windows.h. Hàm này có kiểu trả về là BOOL và trả về giá trị là thời gian tính bằng giây từ lúc chương trình bắt đầu chạy, tham số đầu vào là con trỏ tới một biến kiểu LARGE_INTEGER.
Ví dụ sau là chương trình đo thời gian thực hiện 600000000 vòng lặp rỗng:
// file timer4w.c
#include
#include
// khai bao cau truc va cac ham
typedef struct {
LARGE_INTEGER start;
LARGE_INTEGER stop;
} stopWatch;
void startTimer( stopWatch *timer) ;
void stopTimer( stopWatch *timer) ;
double LIToSecs( LARGE_INTEGER * L) ;
double getElapsedTime( stopWatch *timer);
void startTimer( stopWatch *timer)
{
QueryPerformanceCounter(&timer->start) ;
}
void stopTimer( stopWatch *timer)
{
QueryPerformanceCounter(&timer->stop) ;
}
double LIToSecs( LARGE_INTEGER * L)
{
LARGE_INTEGER frequency;
QueryPerformanceFrequency( &frequency ) ;
return ((double)L->QuadPart /(double)frequency.QuadPart) ;
}
double getElapsedTime( stopWatch *timer) {
LARGE_INTEGER time;
time.QuadPart = timer->stop.QuadPart – timer->start.QuadPart;
return LIToSecs( &time) ;
}
// su dung cac ham
int main()
{
long i = 600000000L;
stopWatch timer;
double duration;
// Do thoi gian cua mot su kien
printf( “Thoi gian thuc hien %ld vong lap rong:”, i );
startTimer(&timer);
while( i– )
;
stopTimer(&timer);
duration = getElapsedTime(&timer);
printf( “%2.1f giay\n”, duration );
system(“pause”);
return 0;
}
3. Đo thời gian thực hiện của chương trình với C++ trên Windows
Tương tự như đối với chương trình C trên Windows, ở đây ta cũng sử dụng hàm QueryPerformanceCounter(LARGE_INTEGER *), tuy nhiên ta xây dựng lớp CStopWatch để tiện dùng cho các chương trình khác nhau.
// file timer4w.cpp
#include
#include
using namespace std;
typedef struct {
LARGE_INTEGER start;
LARGE_INTEGER stop;
} stopWatch;
// khai bao lop CStopWatch
class CStopWatch {
private:
stopWatch timer;
LARGE_INTEGER frequency;
double LIToSecs( LARGE_INTEGER & L) ;
public:
CStopWatch() ;
void startTimer( ) ;
void stopTimer( ) ;
double getElapsedTime() ;
};
double CStopWatch::LIToSecs( LARGE_INTEGER & L)
{
return ((double)L.QuadPart /(double)frequency.QuadPart) ;
}
CStopWatch::CStopWatch()
{
timer.start.QuadPart=0;
timer.stop.QuadPart=0;
QueryPerformanceFrequency( &frequency ) ;
}
void CStopWatch::startTimer( )
{
QueryPerformanceCounter(&timer.start) ;
}
void CStopWatch::stopTimer( )
{
QueryPerformanceCounter(&timer.stop) ;
}
double CStopWatch::getElapsedTime()
{
LARGE_INTEGER time;
time.QuadPart = timer.stop.QuadPart – timer.start.QuadPart;
return LIToSecs( time) ;
}
// su dung lop CStopWatch
int main()
{
long i = 600000000L;
CStopWatch timer;
double duration;
// Do thoi gian cua mot su kien
printf( “Thoi gian thuc hien %ld vong lap rong:”, i );
timer.startTimer();
while( i– )
;
timer.stopTimer();
duration = timer.getElapsedTime();
printf( “%2.1f giay\n”, duration );
system(“pause”);
return 0;
}
4. Đo thời gian thực hiện của chương trình với C#
Bắt đầu từ .NET Framework 2.0, lớp StopWatch được cung cấp cho người dùng để tiến hành các công việc liên quan tới đo đếm thời gian thực hiện 1 tác vụ nào đó, lớp này nằm trong namespace System.Diagnostics.
Ví dụ sau đây là chương trình đo thời gian thực hiện 600000000 vòng lặp rỗng:
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
namespace Timer
{
class Program
{
static void Main(string[] args)
{
Stopwatch st = new Stopwatch();
st.Start();
long i = 600000000L;
Console.WriteLine(“Thoi gian thuc hien {0} vong lap rong:”, i);
while (i > 0)
–i;
st.Stop();
Console.WriteLine(“{0} giay”, st.Elapsed.ToString());
if (Stopwatch.IsHighResolution)
Console.WriteLine(“Timed with Hi res”);
else
Console.WriteLine(“Not Timed with Hi res”);
Console.ReadKey();
}
}
}
5. Tài liệu tham khảo
1. MSDN 9.0, clock function (ms-help://MS.VSCC.v90/MS.MSDNQTR.v90.en/dv_vccrt/html/3e1853dd-498f-49ba-b06a-f2315f20904e.htm).
2. http://cplus.about.com/od/howtodothingsin1/a/timing.htm
3. http://cplus.about.com/od/howtodothingsi2/a/timing.htm
4. http://cplus.about.com/od/howtodothingsinc/a/timing.htm
5. Microsoft® Windows® Internals, Fourth Edition: Microsoft Windows Server™ 2003, Windows XP, and Windows 2000, Mark E. Russinovich, David A. Solomon

Mặc dù đã hết sức thận trọng và xem xét kỹ lưỡng các ví dụ đưa ra trong bài viết, tuy vậy vẫn có thể không tránh khỏi các sai sót, rất mong nhận được sự đóng góp ý kiến của các bạn độc giả. Mọi góp ý, thắc mắc xin gửi về địa chỉ email: tuannhtn@yahoo.com.

Office 2007 SP2 – New SP of the MS SPs

Microsoft mới đưa ra bản SP 2 cho bộ phần mềm văn phòng Office 2007 vào ngày 24/4/2009. Ngày 24/4 có lẽ là một ngày hoàng đạo với Microsoft, còn nhớ cũng ngày này năm ngoái là bản SP3 của Windows XP được xuất xưởng (bản này chạy rất ổn). Người dùng có thể download và tự chạy phần Update lên SP2 cho bản Office 2007. Bản Update này có dung lượng 290 Mb. Có lẽ giống như trong âm nhạc thường các bản số 9 nghe bao giờ cũng hay hơn (chẳng hạn như các bản giao hưởng số 9 của các bậc tiền bối Beethoven, Mozart, Bach thường là hay hơn các bản khác). Còn trong thế giới phần mềm, và nhất là với các phần mềm của Microsoft, các bản SP bao giờ cũng tốt hơn.
Download Office 2007 SP2 tại đây

Windows có bao nhiêu Version?

Do cách dùng tiếng Anh và việc hiểu tiếng Anh dẫn tới việc nhiều bạn hiểu về các phiên bản của hệ điều hành Windows chưa được đúng lắm. Ví dụ có bạn cho rằng Windows XP Professional Edition và Windows XP Home Edition là hai phiên bản khác nhau của hệ điều hành Windows. Thực ra như vậy vừa đúng lại vừa không đúng, đúng là Windows XP Professional Edition và Windows XP Home Edition là hai Edition khác nhau của cùng 1 Version Windows XP, có lẽ sai là vì hiểu từ Edition và Version sai. Version có nghĩa là một phiên bản, thường đi kèm với các số hiệu của phiên bản (1.0, 1.2. … 5.0) và thường là một thay đổi lớn đối với bản thân phần mềm, ví dụ như đối với Windows thì có 3 thay đổi lớn: thay đổi về kiến trúc nền tảng của hệ điều hành (tức là phần kernel của hệ điều hành), hai là cập nhật các bản vá (patch) cho các lỗi của phiên bản trước đó đối với tất cả các phần của hệ điều hành, ba là các phần mới của hệ điều hành (có thể là các ứng dụng đi kèm hoặc hỗ trợ thêm các công nghệ mới, ví dụ như đối với Windows là chuẩn Wi-Fi, DVD, dot NET framework hay các ứng dụng như Windows Media Player, IE …).
Còn Edition là ấn bản khác nhau của cùng một phiên bản, các Edition thường gắn với các yếu tố về địa lý, ngôn ngữ khác nhau (ví dụ như Compact Edition nghĩa là bản rút gọn, Standard Edition là bản chuẩn, Ultimate Edition là bản có các tính năng cao cấp nhất …). Đối với hệ điều hành Windows các Edition khác nhau thường phân biệt bởi các tính năng của chúng, do nhắm tới việc phục vụ các đối tượng khác nhau nên Microsoft bỏ đi một số tính năng không cần thiết và tăng thêm các tính năng mà đối tượng người dùng hay dùng ví dụ như bản Home Edition nhắm tới người dùng gia đình nên các tính năng đồ họa, video, âm thanh phải tốt, còn bản Professional nhắm tới các người dùng chuyên nghiệp có trình độ cao nên các tính năng hệ thống sẽ cao hơn.
Windows có các phiên bản sau đây:
Windows 1.01
Windows 2.03
Windows 2.11
Windows 3.0
Windows 3.1x
Windows For Workgroups 3.1
Windows NT 3.1
Windows For Workgroups 3.11
Windows 3.2 (released in Simplified Chinese only)
Windows NT 3.5
Windows NT 3.51
Windows 95
Windows NT 4.0
Windows 98
Windows 98 SE
Windows 2000
Windows Me
Windows XP
Windows XP 64-bit Edition 2003
Windows Server 2003
Windows XP Professional x64 Edition
Windows Fundamentals for Legacy PCs
Windows Vista
Windows Home Server
Windows Server 2008
Windows 7

Tham khảo từ Wikipedia: http://en.wikipedia.org/wiki/Microsoft_Windows
Tất nhiên là mỗi Version trên lại có nhiều Edition khác nhau.
Phần nhân (Kernel – Core) của hệ điều hành luôn là phần quan trọng nhất của một hệ điều hành. Đối với Windows nhân gồm 3 thành phần: các dịch vụ chạy ở mức nhân (kernel-mode service, để phân biệt với các dịch vụ chạy ở mức ứng dụng) gồm các thư viện chính của hệ điều hành, các thư viện thực hiện quản lý tiến trình, lập lịch, quản lý vào ra dữ liệu trên đĩa cứng, bộ nhớ. Phần 2 là các thư viện làm việc với các phần cứng ở mức chung, phần 3 là các Diver. Thực ra thì để tìm hiểu hết về nhân của hệ điều hành Windows cũng như các khái niệm liên quan thì cũng đòi hỏi mất nhiều thời gian và công lực, các bạn có thể tham khảo thêm bằng cách đọc cuốn “Microsoft® Windows® Internals, Fourth Edition: Microsoft Windows Server™ 2003, Windows XP, and Windows 2000” của các tác giả “Mark E. Russinovich, David A. Solomon” hoặc đọc tài liệu http://www.i.u-tokyo.ac.jp/edu/training/ss/lecture/new-documents/Lectures/00-WindowsKernelOverview/WindowsKernelOverview.pdf.

Inspired by kids

Nơi giải đáp thắc mắc về các chủ đề của Blog. You are Welcome.

Bài tập C – Học ngày 8/5/2009

Chủ đề:
1. File trong C
2. Sinh số ngẫu nhiên
3. Số nguyên tố
4. Xử lý mảng
Đề bài:
Viết chương trình sinh n số nguyên ngẫu nhiên (mỗi số không quá 10000, n không quá 1000), ghi mảng vào file dat1.txt: đầu tiên là số phần tử (n) sau đó là các số nguyên, các số ngăn cách với nhau bằng 1 dấu cách. Đọc các số nguyên từ file dat1.txt sau đó ghi các số nguyên tố vào file nguyento.txt theo định dạng giống như file dat1.txt.
Thuật toán để kiểm tra các số nguyên từ file dat1.txt và ghi vào file nguyento.txt:
Dùng biến m để lưu số lượng số nguyên tố, ban đầu m bằng 0, sử dụng mảng x để lưu các số nguyên tố đọc được từ file dat1.txt, mỗi lần đọc ra một số và kiểm tra, nếu đúng là số nguyên tố thì tăng m lên 1 đơn vị.
Lời giải:
// Bai giang tren lop ngay 8/5/2009
// Nguyen Huu Tuan – Dai hoc Hang hai Viet Nam
// Email: tuannhtn@yahoo.com, tuannhtn@gmail.com
// Blog: 4fire.wordpress.com

#include
#include
void sinhngaunhien(char * tenfile, int n, int maxval);
void docfile(char * tenfile);
void songuyento(char * file1, char * file2);
int ktnguyento(int n);

int main()
{
int n;
int maxval = 1000;
char file1[] = “dat1.txt”;
char file2[13] = “nt.txt”;
printf(“Nhap n = “);
scanf(“%d”, &n);
sinhngaunhien(file1, n, maxval);
printf(“File ngau nhien:\n”);
docfile(file1);
songuyento(file1, file2);
printf(“\nFile chua cac so nguyen to:\n”);
docfile(file2);
system(“pause”);
return 0;
}

int ktnguyento(int n)
{
int i;
int m;
if (n==1)
return 0;
m = (int)sqrt(n);
for(i=2;i<=m;i++)
if(n % i == 0)
return 0;
return 1;
}

void sinhngaunhien(char * tenfile, int n, int maxval)
{
// sinh ngau nhien n so nguyen nho hon maxval
// ghi n so nguyen vao file co ten la tenfile
int i, x;
FILE * f;
f = fopen(tenfile,”wt”);
if(f==NULL)
{
printf(“Loi mo file %s”, tenfile);
return;
}
srand(time(NULL));
fprintf(f, “%d “, n);
for(i=0;i<n;++i)
{
x = rand() % maxval;
fprintf(f, “%d “, x);
}
fclose(f);
}
void songuyento(char * file1, char * file2)
{
int n, m, i;
int x[10000];
FILE * f1, *f2;
f1 = fopen(file1,”rt”);
f2 = fopen(file2,”wt”);
if(f1==NULL||f2==NULL)
{
printf(“Loi mo file”);
return;
}
fscanf(f1,”%d”, &n);
m = 0;
for(i=0;i<n;++i)
{
fscanf(f1,”%d”, &x[m]);
if(ktnguyento(x[m])==1)
m++;
}
fprintf(f2, “%d “, m);
for(i=0;i<m;++i)
fprintf(f2, “%d “, x[i]);
fclose(f1);
fclose(f2);
}
void docfile(char * tenfile)
{
int i, n;
int x;
FILE * f = fopen(tenfile, “rt”);
if(f==NULL)
{
printf(“Loi mo file %s”, tenfile);
return;
}
fscanf(f,”%d”, &n); // doc so phan tu
// doc tung phan tu
for(i=0;i<n;++i)
{
fscanf(f,”%d”, &x);
printf(“%d “, x);
}
fclose(f);
}

Đề cương ôn tập môn Kỹ thuật lập trình C

Đề cương ôn tập môn Kỹ thuật lập trình C dành cho các lớp CNT48ĐH, CNT49ĐH1, CNT49ĐH2:Download