Bốn bản phân phối cốt lõi [, , và ] đều cho phép các mảng hiện có được lấp đầy bằng cách sử dụng đối số từ khóa
In [2]: mrng = MultithreadedRNG[10000000, seed=12345] ...: print[mrng.values[-1]] Out[2]: 0.0 In [3]: mrng.fill[] ...: print[mrng.values[-1]] Out[3]: 2.45457245174791040. Các mảng hiện có cần phải liền kề và hoạt động tốt [có thể ghi và căn chỉnh]. Trong các trường hợp bình thường, các mảng được tạo bằng cách sử dụng các hàm tạo phổ biến như sẽ đáp ứng các yêu cầu này
Ví dụ này sử dụng Python 3 để điền vào một mảng bằng nhiều luồng. Các luồng tồn tại lâu dài để các cuộc gọi lặp lại không yêu cầu bất kỳ chi phí bổ sung nào từ việc tạo luồng
Các số ngẫu nhiên được tạo có thể tái tạo theo nghĩa là cùng một hạt giống sẽ tạo ra các đầu ra giống nhau, với điều kiện là số lượng luồng không thay đổi
from numpy.random import default_rng, SeedSequence import multiprocessing import concurrent.futures import numpy as np class MultithreadedRNG: def __init__[self, n, seed=None, threads=None]: if threads is None: threads = multiprocessing.cpu_count[] self.threads = threads seq = SeedSequence[seed] self._random_generators = [default_rng[s] for s in seq.spawn[threads]] self.n = n self.executor = concurrent.futures.ThreadPoolExecutor[threads] self.values = np.empty[n] self.step = np.ceil[n / threads].astype[np.int_] def fill[self]: def _fill[random_state, out, first, last]: random_state.standard_normal[out=out[first:last]] futures = {} for i in range[self.threads]: args = [_fill, self._random_generators[i], self.values, i * self.step, [i + 1] * self.step] futures[self.executor.submit[*args]] = i concurrent.futures.wait[futures] def __del__[self]: self.executor.shutdown[False]
Trình tạo số ngẫu nhiên đa luồng có thể được sử dụng để điền vào một mảng. Các thuộc tính
In [2]: mrng = MultithreadedRNG[10000000, seed=12345] ...: print[mrng.values[-1]] Out[2]: 0.0 In [3]: mrng.fill[] ...: print[mrng.values[-1]] Out[3]: 2.45457245174791043 hiển thị giá trị 0 trước khi điền và giá trị ngẫu nhiên sau
In [2]: mrng = MultithreadedRNG[10000000, seed=12345] ...: print[mrng.values[-1]] Out[2]: 0.0 In [3]: mrng.fill[] ...: print[mrng.values[-1]] Out[3]: 2.4545724517479104
Thời gian cần thiết để tạo bằng nhiều luồng có thể được so sánh với thời gian cần thiết để tạo bằng một luồng
In [4]: print[mrng.threads] ...: %timeit mrng.fill[] Out[4]: 4 ...: 32.8 ms ± 2.71 ms per loop [mean ± std. dev. of 7 runs, 10 loops each]
Cuộc gọi luồng đơn trực tiếp sử dụng BitGenerator
In [5]: values = np.empty[10000000] ...: rg = default_rng[] ...: %timeit rg.standard_normal[out=values] Out[5]: 99.6 ms ± 222 µs per loop [mean ± std. dev. of 7 runs, 10 loops each]
Mức tăng là đáng kể và tỷ lệ hợp lý ngay cả đối với các mảng chỉ lớn vừa phải. Mức tăng thậm chí còn lớn hơn khi so sánh với một cuộc gọi không sử dụng mảng hiện có do chi phí tạo mảng