Nhờ các bạn test thời gian dùm 2 thủ tục (1 người xem)

Liên hệ QC

Người dùng đang xem chủ đề này

Hoàng Trọng Nghĩa

Chuyên gia GPE
Thành viên BQT
Moderator
Tham gia
17/8/08
Bài viết
8,662
Được thích
16,725
Giới tính
Nam
Tôi có 2 thủ tục, về bản chất và logic nó không có gì khác nhau, chỉ đảo vòng lặp trước và sau:

Mã:
Sub ThiNghiem1()
    Dim t As Double
    Dim r As Long, c As Byte
    Dim ArrTest(1 To 1000000, 1 To 10)
    t = Timer
[COLOR=#0000cd]    For r = 1 To 1000000[/COLOR]
        For c = 1 To 10
            ArrTest(r, c) = "HTN" & r & c
        Next
    Next
    Debug.Print Timer - t
End Sub


Sub ThiNghiem2()
    Dim t As Double
    Dim r As Long, c As Byte
    Dim ArrTest(1 To 1000000, 1 To 10)
    t = Timer
    For c = 1 To 10
[COLOR=#ff0000]        For r = 1 To 1000000[/COLOR]
            ArrTest(r, c) = "HTN" & r & c
        Next
    Next
    Debug.Print Timer - t
End Sub

Nhờ các bạn test hộ xem thủ tục nào chạy nhanh hơn nhé (test ít nhất mỗi thủ tục 3 lần). Trong VBE, mở Immediate (Ctrl+G) để xem kết quả thời gian.

Các bạn cho mình biết ý kiến về sự khác biệt nhé! Cám ơn rất nhiều.
 
Test lần lượt 3 lần
ThiNghiem1() : 10,55078125 9,984375 10,0625
ThiNghiem2(): 9,78125 9,69140625 9,67578125
 
Upvote 0
Thằng Sub ThiNghiem1 cho kết quả:

6.3046875
6.1328125
6.1328125

Thằng Sub ThiNghiem2 cho kết quả:

6.046875
5.99609375
6.12109375

--=0

PS: Thời gian khác nhau giữa máy tôi và anh hieuxd còn liên quan đến cấu hình máy tính. Nhưng đúng quy luật là chắc!
 
Upvote 0
Tôi có 2 thủ tục, về bản chất và logic nó không có gì khác nhau, chỉ đảo vòng lặp trước và sau:

Câu này không chính xác, có khác nhau
----------------

Thử hình dung - ví dụ này cho bạn dễ hiểu:
Cùng đi đến đích là 1000km, nhưng nếu

cách 1: có 10 lần phải quẹo (vòng/cua) trên quãng đường (tức là 100 km 1 lần cua)
cách 2: có 100 lần phải quẹo (vòng/cua) trên quãng đường (tức là 10 km 1 lần cua)

Vậy KHÁC NHAU XA về logic và bản chất của 2 cách trên
 
Lần chỉnh sửa cuối:
Upvote 0
Thằng Sub ThiNghiem1 cho kết quả:

6.3046875
6.1328125
6.1328125

Thằng Sub ThiNghiem2 cho kết quả:

6.046875
5.99609375
6.12109375

--=0

PS: Thời gian khác nhau giữa máy tôi và anh hieuxd còn liên quan đến cấu hình máy tính. Nhưng đúng quy luật là chắc!

So sánh 2 kết quả chạy đang ấm ức muốn thay em yêu này
Máy của em đúng là cấu hình cũ rích chạy từ năm 2008 đến nay
Chạy chậm hơn của thầy 1/3 rồi
 
Upvote 0
Lần chỉnh sửa cuối:
Upvote 0
Câu này không chính xác, có khác nhau
----------------

Thử hình dung - ví dụ này cho bạn dễ hiểu:
Cùng đi đến đích là 1000km, nhưng nếu

cách 1: có 10 lần phải quẹo (vòng/cua) trên quãng đường (tức là 100 km 1 lần cua)
cách 2: có 100 lần phải quẹo (vòng/cua) trên quãng đường (tức là 10 km 1 lần cua)

Vậy KHÁC NHAU XA về logic và bản chất của 2 cách trên
Thế rồi bạn có kết luận thủ tục nào nhanh hơn giữa 2 code kia không?
 
Upvote 0
Trên một máy WinXP khác, Excel 2003

ThiNghiem1:

7.859375
7.4375
7.40625

ThiNghiem2:

7.265625
7.28125
7.234375

Nhìn các thí nghiệm cho đến hiện giờ, đa phần ThiNghiem2 có phần ít hơn về thời gian tí xíu.
 
Upvote 0
Tôi trả lời hộ bạn vodoi2x.

Tôi lấy vd. khác để thấy rõ sự khác biệt

Ta có 10 dãy nhà (10 cột), trong mỗi dãy nhà có 1000000 căn hộ liên tiếp nhau.

1. Người trao giấy mời đi hết các nhà theo cách: đi nhà 1 của dãy 1, 2, ..., 10, đi nhà 2 của dãy 1, 2, ..., 10, ..., đi nhà 1000000 của dãy 1, 2, ..., 10

2. Người trao giấy mời đi hết các nhà theo cách: đi hết các nhà 1, 2, ..., 1000000 của dãy 1, ..., đi hết các nhà 1, 2, ..., 1000000 của dãy 10

Rõ ràng 2 cách là khác nhau.

Thế rồi bạn có kết luận thủ tục nào nhanh hơn giữa 2 code kia không?

Trong VBA mảng 2 chiều được ghi trong bộ nhớ bằng các CỘT liên tiếp, tức
<các phần tử liên tiếp của cột 1><các phần tử liên tiếp của cột 2>...<các phần tử liên tiếp của cột k>

Nói cách khác thì 2 phần tử liên tiếp cùng cột thì nằm liền nhau còn 2 phần tử liên tiếp cùng hàng thì nằm ở 2 chỗ cách nhau. Tức đọc 2 ô liên tiếp cùng cột thì "bình thường" còn đọc 2 ô liên tiếp cùng hàng thì phải "nhẩy cóc" sang chỗ khác.

Với cách 1 phải nhẩy cóc liên tục:

a(1, 1)<nhẩy cóc>a(1, 2)<nhẩy cóc>...a(1, 9)<nhẩy cóc>a(1, 10)<nhẩy cóc>
a(2, 1)<nhẩy cóc>a(2, 2)<nhẩy cóc>...a(2, 9)<nhẩy cóc>a(2, 10)<nhẩy cóc>
...
a(1000000, 1)<nhẩy cóc>a(1000000, 2)<nhẩy cóc>...a(1000000, 9)<nhẩy cóc>a(1000000, 10)

Vậy theo tôi, tức không test gì cả mà chỉ suy luận thôi, cách 2 tốn ít thời gian hơn.

Chú ý là tôi viết "theo tôi" chứ không cho đó là tiên đề.
 
Lần chỉnh sửa cuối:
Upvote 0
Từ việc lập luận/ lý thuyết, đến thực hành, ta đều thấy thủ tục 2 nhanh hơn thủ tục 1.

Đó cũng là lý do tại sao tôi gửi bài này lên để mọi người nhận thức được điều đó. Hầu hết những bài viết về mảng, vùng của các bạn trên diễn đàn, trong đó có tôi, đều có kiểu viết 2 vòng lặp với kiểu Row trước rồi mới đến Column sau.

Từ bài này chúng ta có thể thay đổi cách viết của mình sao cho hợp lý nhất!

Trân trọng.
 
Upvote 0
Từ việc lập luận/ lý thuyết, đến thực hành, ta đều thấy thủ tục 2 nhanh hơn thủ tục 1.

Đó cũng là lý do tại sao tôi gửi bài này lên để mọi người nhận thức được điều đó. Hầu hết những bài viết về mảng, vùng của các bạn trên diễn đàn, trong đó có tôi, đều có kiểu viết 2 vòng lặp với kiểu Row trước rồi mới đến Column sau.

Từ bài này chúng ta có thể thay đổi cách viết của mình sao cho hợp lý nhất!

Trân trọng.

Cũng không cần cân bằng cân tiểu ly đâu bạn ạ. Về lý thuyết có thể nhanh hơn nhưng những bước "nhẩy cóc" rất nhanh mà. Bạn cũng thấy là với mảng hàng triệu ô thì "lãi" của bạn là bao nhiêu. Trong thực tế thì mấy khi phải nhập giá trị vào mảng kiểu đó? Thường những code trên GPE là đập từ sheet vào mảng. Những th phải nhập kiểu của bạn lại rất ít, kích cỡ mảng cũng không phải hàng triệu dòng vậy thì lãi được bao nhiêu? Còn nếu không nói về nhập dữ liệu vào mảng mà xét về duyệt mảng thì thực tế là trong đa số th bạn phải duyệt theo dòng để điểm tra một đk nào đó để rồi khi thỏa đk thì mới duyệt theo cột đễ lấy dữ liệu. Bạn không thể duyệt theo cột được. Lý do là "cuộc sống" đã chấp nhận là mỗi dòng là 1 record. Tức các record có cấu trúc như nhau, còn mỗi cột là 1 field. Vì thế "duyệt" csdl luôn là duyệt theo dòng - field.

Mà nếu nói về lãi khi nhập dữ liệu vào mảng thì chỉ nên bật tâm về thứ tự nhập khi mà phải nhập vào mảng cực cực lớn và cái việc nhập đó là "liên tục", cỡ ít ra là vài lần trong 1 phút?. Còn không thì quên đi.
 
Upvote 0
Cũng không cần cân bằng cân tiểu ly đâu bạn ạ. Về lý thuyết có thể nhanh hơn nhưng những bước "nhẩy cóc" rất nhanh mà. Bạn cũng thấy là với mảng hàng triệu ô thì "lãi" của bạn là bao nhiêu. Trong thực tế thì mấy khi phải nhập giá trị vào mảng kiểu đó? Thường những code trên GPE là đập từ sheet vào mảng. Những th phải nhập kiểu của bạn lại rất ít, kích cỡ mảng cũng không phải hàng triệu dòng vậy thì lãi được bao nhiêu? Còn nếu không nói về nhập dữ liệu vào mảng mà xét về duyệt mảng thì thực tế là trong đa số th bạn phải duyệt theo dòng để điểm tra một đk nào đó để rồi khi thỏa đk thì mới duyệt theo cột đễ lấy dữ liệu. Bạn không thể duyệt theo cột được. Lý do là "cuộc sống" đã chấp nhận là mỗi dòng là 1 record. Tức các record có cấu trúc như nhau, còn mỗi cột là 1 field. Vì thế "duyệt" csdl luôn là duyệt theo dòng - field.

Mà nếu nói về lãi khi nhập dữ liệu vào mảng thì chỉ nên bật tâm về thứ tự nhập khi mà phải nhập vào mảng cực cực lớn và cái việc nhập đó là "liên tục", cỡ ít ra là vài lần trong 1 phút?. Còn không thì quên đi.


Có người nói ta chỉ cần khai báo DIM BIEN là đủ rồi, không cần phải khai báo thêm kiểu DATA TYPE nữa, nó vẫn chạy, cần chi phải tì mì tỉ mĩ làm gì, so ra cũng chả chậm gì hết!

Vấn đề không phải là "cu ki" từng tí một mà đó là phải tập thói quen làm sao cho cách viết của mình càng tiến tới hợp lý nhất, từng bước chuyên nghiệp, chứ không phải là "hà tiện".

Riêng lọc dữ liệu, tôi thường xuyên lọc cột điều kiện để lấy Row Index trước rồi mới xuất mảng theo các GetRows này, nên không quan tâm về hàng hay cột trước.
 
Upvote 0
Có người nói ta chỉ cần khai báo DIM BIEN là đủ rồi, không cần phải khai báo thêm kiểu DATA TYPE nữa, nó vẫn chạy, cần chi phải tì mì tỉ mĩ làm gì, so ra cũng chả chậm gì hết!

Vấn đề không phải là "cu ki" từng tí một mà đó là phải tập thói quen làm sao cho cách viết của mình càng tiến tới hợp lý nhất, từng bước chuyên nghiệp, chứ không phải là "hà tiện".

Riêng lọc dữ liệu, tôi thường xuyên lọc cột điều kiện để lấy Row Index trước rồi mới xuất mảng theo các GetRows này, nên không quan tâm về hàng hay cột trước.

Cái nào cái ấy rõ ràng bạn ạ.
Cái kiểu nhập như của bạn làm thường xuyên tới mức nào? Cỡ mảng là mấy triệu dòng?
Tôi không phủ nhận là nhập theo cột nhanh hơn. Nhưng chỉ cần ý thức thôi. Khi cần thì nhập theo cột. Chỉ có điều những th phải nhập vào mảng kiểu đó rất hiếm, rất ít khi làm.
Còn biến Variant ư? Cái này thì hơi khác. Nếu giá trị là Long mà biến đó dùng trong vòng lặp hàng trăm nghìn vòng kiểu: bien = xyz, nếu thì thì biến đó dùng liên tục, bị khai khác đến chóng mặt rồi. Cái vụ nhập vào mảng của bạn đâu có thể so sánh với vd. bien kia được?

Mà tôi chỉ nói là cũng không cần chi li tới mức như thế vì tần số dùng cũng không cao, lãi cũng chả là mấy. Tất nhiên phải ý thức được và khi thực sự là cần đến thì biết cách mà viết.

Chuyện duyệt để lấy row index rồi sau đó mới duyệt theo cột để lấy dữ liệu thì không chỉ bạn mới biết làm. Nhưng rõ ràng là bạn phải duyệt theo DÒNG để lấy những index?

Bạn có ý kiến, tôi cũng có ý kiến. Nhưng rồi mỗi người sẽ tự mình làm sao cho nó đúng thôi.

Ý kiến thế thôi chứ tôi đâu có muốn tranh cãi gì. Chấm hết ở đây.
 
Upvote 0
Từ việc lập luận/ lý thuyết, đến thực hành, ta đều thấy thủ tục 2 nhanh hơn thủ tục 1.

Đó cũng là lý do tại sao tôi gửi bài này lên để mọi người nhận thức được điều đó. Hầu hết những bài viết về mảng, vùng của các bạn trên diễn đàn, trong đó có tôi, đều có kiểu viết 2 vòng lặp với kiểu Row trước rồi mới đến Column sau.

Từ bài này chúng ta có thể thay đổi cách viết của mình sao cho hợp lý nhất!

Trân trọng.


Có người nói ta chỉ cần khai báo DIM BIEN là đủ rồi, không cần phải khai báo thêm kiểu DATA TYPE nữa, nó vẫn chạy, cần chi phải tì mì tỉ mĩ làm gì, so ra cũng chả chậm gì hết!

Vấn đề không phải là "cu ki" từng tí một mà đó là phải tập thói quen làm sao cho cách viết của mình càng tiến tới hợp lý nhất, từng bước chuyên nghiệp, chứ không phải là "hà tiện".

Riêng lọc dữ liệu, tôi thường xuyên lọc cột điều kiện để lấy Row Index trước rồi mới xuất mảng theo các GetRows này, nên không quan tâm về hàng hay cột trước.

Hợp lý và chuyên nghiệp có thể mang tính chất tương đối và chủ quan.

Lý nằm ở chỗ ta muốn nhìn dữ liệu bảng theo cột hay theo dòng.
Đối với người làm toán chuyên nghiệp, ma trận có thể không phân biệt thứ tự dòng và cột. Nhưng đối với dân chuyên nghiệp CSDL liên hệ, dữ liệu phải được diễn giải theo dòng.
 
Upvote 0
window dùng một phần ổ cứng làm bộ nhớ ảo. với win 32 thì bộ nhớ ảo là 4gb, trong khi mấy máy cũ ram chỉ có vài chục đến vài trăm mb. ram càng nhỏ thì số lần swaping dữ liệu giữa bộ nhớ ảo với ram càng nhiều. mặt khác khi tính với c trước thì mỗi lần tính chỉ xài rất ít dữ liệu cho nên để duyêt cho hết cần swaping nhiều lần hơn. thời gian phát sinh do swaping chứ không do tính toán (thời gian dành cho tính toán là như nhau)
 
Upvote 0

Bài viết mới nhất

Back
Top Bottom