Warum führen meine zeilenbasierten vs. spaltenbasierten und iterativen vs. indexbasierten Array-Zugriffstests zu unerwarPython

Python-Programme
Guest
 Warum führen meine zeilenbasierten vs. spaltenbasierten und iterativen vs. indexbasierten Array-Zugriffstests zu unerwar

Post by Guest »

Ich lese das Buch Designing Machine Learning Systems von Chip Huyen (Amazon Link). In Kapitel 3, Abschnitt Row-Major- und Column-Major-Format, erklärt das Buch, dass bei Arrays mit Zeilenhauptgröße der Zugriff auf Daten nach Zeilen schneller sein sollte als nach Spalten, und umgekehrt für Arrays mit Spaltenhauptgröße .
Als ich jedoch einige Testfälle schrieb, überraschten mich die Ergebnisse. Ich habe zwei Fragen:
  • Meine Ergebnisse zeigen, dass die Hauptordnung des Arrays keinen Einfluss auf die Zugriffsgeschwindigkeit zu haben scheint, was unerwartet ist. Warum passiert das?
  • Ich habe zwei Methoden getestet, um auf das Array zuzugreifen: indexbasierten Zugriff und Iteration. Ich habe erwartet, dass sie die gleiche Leistung erbringen, da beide die gleiche Komplexität haben. Meine Ergebnisse zeigen jedoch, dass die Iterationsmethode den indexbasierten Zugriff übertrifft. Warum ist das so?
Hier ist der Code, den ich zum Testen verwendet habe:
< pre class="lang-py Prettyprint-override">

Code: Select all

from time import perf_counter
import numpy as np

def test_column_access_numpy_index(array):
n_row, n_col = array.shape
start = perf_counter()
for j in range(n_col):
for i in  range(n_row):
_ = array[i, j]
return perf_counter() - start

def test_row_access_numpy_index(array):
n_row, n_col = array.shape
start = perf_counter()
for i in range(n_row):
for j in range(n_col):
_ = array[i, j]
return perf_counter() - start

def test_column_access_numpy_iteration(array):
n_row, n_col = array.shape
start = perf_counter()
for j in range(n_col):
for item in array[:, j]:
pass
return perf_counter() - start

def test_row_access_numpy_iteration(array):
n_row, n_col = array.shape
start = perf_counter()
for i in range(n_row):
for item in array[i]:
pass
return perf_counter() - start

if __name__=='__main__':
size = 10_000
row_major = np.ones((size, size), dtype=np.float32, order='C')
col_major = np.ones((size, size), dtype=np.float32, order='F')

print("Warm up")
test_row_access_numpy_iteration(row_major)

print("Input row major")

time = test_row_access_numpy_index(row_major)
print(f"Testing row access index in numpy: {time:.6f} seconds")

time = test_column_access_numpy_index(row_major)
print(f"Testing column access index in numpy: {time:.6f} seconds")

time = test_row_access_numpy_iteration(row_major)
print(f"Testing row access iteration in numpy: {time:.6f} seconds")

time = test_column_access_numpy_iteration(row_major)
print(f"Testing column access iteration in numpy: {time:.6f} seconds")

print('----------------------------')
print("Input col major")

time = test_row_access_numpy_index(col_major)
print(f"Testing row access index in numpy: {time:.6f} seconds")

time = test_column_access_numpy_index(col_major)
print(f"Testing column access index in numpy: {time:.6f} seconds")

time = test_row_access_numpy_iteration(col_major)
print(f"Testing row access iteration in numpy: {time:.6f} seconds")

time = test_column_access_numpy_iteration(col_major)
print(f"Testing column access iteration in numpy: {time:.6f} seconds")

Hier ist das Ausgabeergebnis

Code: Select all

Warm up
Input row major
Testing row access index in numpy: 7.732731 seconds
Testing column access index in numpy: 8.025850 seconds
Testing row access iteration in numpy: 3.111501 seconds
Testing column access iteration in numpy: 3.129321 seconds
----------------------------
Input col major
Testing row access index in numpy: 7.852834 seconds
Testing column access index in numpy: 7.978318 seconds
Testing row access iteration in numpy: 3.027528 seconds
Testing column access iteration in numpy: 3.075494 seconds

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post