Diğerleri söylediler, konu dizideki hafıza konumuna mağaza: x[i][j]
. İşte size nedenlerle ilgili biraz bilgi:
2 boyutlu bir diziniz var, ancak bilgisayardaki bellek doğal olarak 1 boyutlu. Dizinizi böyle hayal ederken:
0,0 | 0,1 | 0,2 | 0,3
----+-----+-----+----
1,0 | 1,1 | 1,2 | 1,3
----+-----+-----+----
2,0 | 2,1 | 2,2 | 2,3
Bilgisayarınız bellekte tek bir satır olarak saklar:
0,0 | 0,1 | 0,2 | 0,3 | 1,0 | 1,1 | 1,2 | 1,3 | 2,0 | 2,1 | 2,2 | 2,3
2. örnekte, diziye önce 2. sayının üzerine döngü yaparak erişirsiniz, yani:
x[0][0]
x[0][1]
x[0][2]
x[0][3]
x[1][0] etc...
Yani hepsini sırayla vuruyorsunuz. Şimdi 1. versiyona bakın. Yapıyoruz:
x[0][0]
x[1][0]
x[2][0]
x[0][1]
x[1][1] etc...
C'nin bellekte 2 boyutlu diziyi yerleştirme biçimi nedeniyle, tüm yere atlamasını istiyorsunuz. Ama şimdi vurucu için: Bu neden önemli? Tüm bellek erişimleri aynı, değil mi?
Hayır: önbellekler yüzünden. Belleğinizdeki veriler CPU'ya küçük parçalar halinde ('önbellek satırları' olarak adlandırılır), genellikle 64 bayt olarak aktarılır. 4 baytlık tamsayılarınız varsa, bu, düzgün küçük bir pakette 16 ardışık tamsayı elde ettiğiniz anlamına gelir. Aslında bu bellek parçalarını almak oldukça yavaş; CPU'nuz tek bir önbellek hattının yüklenmesi için gereken sürede çok iş yapabilir.
Şimdi erişim sırasına tekrar bakın: İkinci örnek (1) 16 inçlik bir yığın kapmak, (2) hepsini değiştirerek, (3) 4000 * 4000/16 kez tekrarlayın. Bu güzel ve hızlı ve CPU'nun üzerinde çalışacağı bir şey var.
İlk örnek (1) 16 inçlik bir yığın kapmak, (2) bunlardan sadece birini değiştirmek, (3) 4000 * 4000 kez tekrarlamaktır. Bu, bellekten "getirme" sayısının 16 katını gerektirir. CPU'nuz aslında bu belleğin görünmesini beklemek için oturup vakit geçirmek zorunda kalacak ve bu sırada otururken değerli zamanınızı boşa harcıyorsunuz.
Önemli Not:
Şimdi cevabınız var, işte ilginç bir not: ikinci örneğinizin hızlı olması için doğal bir neden yok. Örneğin, Fortran'da, ilk örnek hızlı ve ikincisi yavaş olacaktır. Çünkü Fortran, şeyleri C'nin yaptığı gibi kavramsal "satırlara" genişletmek yerine "sütunlara" genişler, yani:
0,0 | 1,0 | 2,0 | 0,1 | 1,1 | 2,1 | 0,2 | 1,2 | 2,2 | 0,3 | 1,3 | 2,3
C düzenine 'row-major' ve Fortran's düzenine 'column-major' denir. Gördüğünüz gibi, programlama dilinizin satır-büyük veya sütun-büyük olduğunu bilmek çok önemlidir! Daha fazla bilgi için bir bağlantı: http://en.wikipedia.org/wiki/Row-major_order