У нас есть приложение, которое до сих пор хранилось исключительно во внешнем интерфейсе, но при тестировании его с большими конфигурациями сетки мы столкнулись с несколькими ограничениями по обработке и памяти.Таким образом, мы исследуем возможность передачи ресурсоемких задач на сервер.
Таким образом, в настоящее время я запускаю несколько тестов, чтобы получить некоторые признаки разницы в производительности, которые мы могли бы увидеть.Более конкретно, учитывая, что значительная часть узкого места в производительности приходится на вложенные циклы, я написал простой фрагмент кода в js и python, чтобы проверить производительность обработки вложенных циклов и построения массива различных размеров.
Моемуудивительно, похоже, что js всегда работает быстрее, независимо от того, что я проверял.
JS-фрагмент:
var timeTotal = 0;
var benchmarkTests = 100;
var testSizes = [50, 100, 500, 1000, 3000];
for (var a = 0; a < testSizes.length; a++) {
var minX = 0;
var maxX = testSizes[a];
var minY = 0;
var maxY = testSizes[a];
var cellDimensionsX = 0.991; // cell width
var cellDimensionsY = 1.652; // cell height
var cellDimensionsXHalf = cellDimensionsX / 2; // half cell width
var cellDimensionsYHalf = cellDimensionsY / 2; // half cell height
var maxCellsXCount = Math.floor(maxX / cellDimensionsX);
var maxCellsYCount = Math.floor(maxY / cellDimensionsY);
console.log("X:", maxCellsXCount, "| Y", maxCellsYCount, "| Total", maxCellsXCount * maxCellsYCount);
for (var k = 0; k < benchmarkTests; k++) {
var cellCoordsTime = new Date().getTime();
var cellCoords = {};
var index = 0;
for (var i = 0; i < maxCellsXCount; i++) {
var xCoord = (i * cellDimensionsX) + cellDimensionsXHalf;
for (var d = 0; d < maxCellsYCount; d++) {
cellCoords[index] = {
x: xCoord,
y: (d * cellDimensionsY) + cellDimensionsYHalf
};
index++;
}
}
var thisTime = new Date().getTime() - cellCoordsTime;
timeTotal += thisTime;
// console.log('cellCoords', thisTime, 'for grid with', index, 'cells');
}
console.log('Testing with a', testSizes[a], '*', testSizes[a], 'grid area. Total time', timeTotal, '. Avg', (timeTotal / benchmarkTests), 'for', benchmarkTests, 'tests');
}
Python-фрагмент:
#!/usr/bin/python
import time
timeTotal = 0
benchmarkTests = 100
testSizes = [50, 100, 500, 1000, 3000]
for a in range(len(testSizes)):
minX = 0
maxX = testSizes[a]
minY = 0
maxY = testSizes[a]
cellDimensionsX = 0.991 # cell width
cellDimensionsY = 1.652 # cell height
cellDimensionsXHalf = cellDimensionsX / 2 # half cell width
cellDimensionsYHalf = cellDimensionsY / 2 # half cell height
maxCellsXCount = int(maxX / cellDimensionsX)
maxCellsYCount = int(maxY / cellDimensionsY)
print("X: %s | Y %s | Total %s" % (maxCellsXCount, maxCellsYCount, maxCellsXCount * maxCellsYCount))
for k in range(benchmarkTests):
start = time.time()
cellCoords = {}
index = 0
for i in range(maxCellsXCount):
xCoord = (i * cellDimensionsX) + cellDimensionsXHalf
for d in range(maxCellsYCount):
cellCoords[index] = {'x': xCoord, 'y': (d * cellDimensionsY) + cellDimensionsYHalf}
index += 1
thisTime = (time.time() - start) * 1000;
timeTotal = timeTotal + thisTime;
# print("Elapsed Time: %s for grid with %s cells" % (thisTime, index))
print("Testing with a %s*%s grid area. Total time %s. Avg %s for %s tests" % (testSizes[a], testSizes[a], timeTotal, (timeTotal / benchmarkTests), benchmarkTests))
При запуске этихЯ получаю:
JS:
Testing with a 50 * 50 grid area. Total time 26 . Avg 0.26 for 100 tests
Testing with a 100 * 100 grid area. Total time 85 . Avg 0.85 for 100 tests
Testing with a 500 * 500 grid area. Total time 4539 . Avg 45.39 for 100 tests
Testing with a 1000 * 1000 grid area. Total time 23160 . Avg 231.6 for 100 tests
Testing with a 3000 * 3000 grid area. Total time 243760 . Avg 2437.6 for 100 tests
Python:
Testing with a 50*50 grid area. Total time 50.8642196655. Avg 0.508642196655 for 100 tests
Testing with a 100*100 grid area. Total time 262.931108475. Avg 2.62931108475 for 100 tests
Testing with a 500*500 grid area. Total time 6338.83333206. Avg 63.3883333206 for 100 tests
Testing with a 1000*1000 grid area. Total time 30769.4478035. Avg 307.694478035 for 100 tests
Testing with a 3000*3000 grid area. Total time 304995.391846. Avg 3049.95391846 for 100 tests
Все времена указаны в мс, и все тесты выполнялись на одном и том же локальном хосте.
Я бы ожидал, что python будет значительно быстрее, чем js.Я что-то упускаю?
ОБНОВЛЕНИЕ № 1 (Перемещено все в функцию | Общий прирост ~ 17%):
Testing with a 50*50 grid area. Total time 41.2473678589. Avg 0.412473678589 for 100 tests
Testing with a 100*100 grid area. Total time 174.555540085. Avg 1.74555540085 for 100 tests
Testing with a 500*500 grid area. Total time 5617.09475517. Avg 56.1709475517 for 100 tests
Testing with a 1000*1000 grid area. Total time 21199.390173. Avg 211.99390173 for 100 tests
Testing with a 3000*3000 grid area. Total time 255921.251535. Avg 2559.21251535 for 100 tests
ОБНОВЛЕНИЕ № 2 (Поменяемый диапазон для xrange | Общий дополнительный прирост после ОБНОВЛЕНИЯ № 1 ~ 15% | Общий прирост по сравнению с исходным кодом ~ 30%):
Testing with a 50*50 grid area. Total time 38.7289524078. Avg 0.387289524078 for 100 tests
Testing with a 100*100 grid area. Total time 176.453590393. Avg 1.76453590393 for 100 tests
Testing with a 500*500 grid area. Total time 5346.49443626. Avg 53.4649443626 for 100 tests
Testing with a 1000*1000 grid area. Total time 21618.1008816. Avg 216.181008816 for 100 tests
Testing with a 3000*3000 grid area. Total time 213622.769356. Avg 2136.22769356 for 100 tests
ОБНОВЛЕНИЕ № 3 (Поменялся местами для списка | Общий дополнительный прирост после ОБНОВЛЕНИЯ № 2 ~ 35% | Общий прирост по сравнению с исходным кодом ~ 55%):
Testing with a 50*50 grid area. Total time 20.7185745239. Avg 0.207185745239 for 100 tests
Testing with a 100*100 grid area. Total time 100.9953022. Avg 1.009953022 for 100 tests
Testing with a 500*500 grid area. Total time 3033.61153603. Avg 30.3361153603 for 100 tests
Testing with a 1000*1000 grid area. Total time 12399.708271. Avg 123.99708271 for 100 tests
Testing with a 3000*3000 grid area. Total time 140118.921518. Avg 1401.18921518 for 100 tests
Соответствие JS с ОБНОВЛЕНИЕМ Python №3 (Поменянный объект для массива | Общая потеря по сравнению с исходным кодом ~ 165%):
Testing with a 50 * 50 grid area. Total time 30 . Avg 0.3 for 100 tests
Testing with a 100 * 100 grid area. Total time 48 . Avg 0.48 for 100 tests
Testing with a 500 * 500 grid area. Total time 12694 . Avg 126.94 for 100 tests
Testing with a 1000 * 1000 grid area. Total time 81402 . Avg 814.02 for 100 tests
Testing with a 3000 * 3000 grid area. Total time 625615 . Avg 6256.15 for 100 tests
ОБНОВЛЕНИЕ № 4 (ЗапрошеноCython в бой | Общий дополнительный прирост после ОБНОВЛЕНИЯ № 3 ~ 26% | Общий прирост по сравнению с исходным кодом ~ 66%):
Testing with a 50*50 grid area. Total time 30. Avg 0.300 for 100 tests
Testing with a 100*100 grid area. Total time 68. Avg 0.680 for 100 tests
Testing with a 500*500 grid area. Total time 2475. Avg 24.750 for 100 tests
Testing with a 1000*1000 grid area. Total time 9924. Avg 99.240 for 100 tests
Testing with a 3000*3000 grid area. Total time 101697. Avg 1016.970 for 100 tests
ОБНОВЛЕНИЕ № 5 (Переменные ввода | Общий дополнительный прирост после ОБНОВЛЕНИЯ № 4 ~ 23% | Общий прирост по сравнению с исходным кодом ~ 74%):
Testing with a 50*50 grid area. Total time 5. Avg 0.048 for 100 tests
Testing with a 100*100 grid area. Total time 43. Avg 0.426 for 100 tests
Testing with a 500*500 grid area. Total time 1851. Avg 18.511 for 100 tests
Testing with a 1000*1000 grid area. Total time 8020. Avg 80.202 for 100 tests
Testing with a 3000*3000 grid area. Total time 78350. Avg 783.502 for 100 tests
(НАДЕЖДА, ФИНAL) ОБНОВЛЕНИЕ № 6 (Оптимизация, связанная с Cython, включая распараллеливание его на 2 ядра |Общий дополнительный прирост после ОБНОВЛЕНИЯ № 5 ~ 88% |Общий выигрыш по сравнению с исходным кодом ~ 97%):
Testing with a 50*50 grid area. Total time 0.668. Avg 0.007 for 100 tests
Testing with a 100*100 grid area. Total time 1.584. Avg 0.016 for 100 tests
Testing with a 500*500 grid area. Total time 57.374. Avg 0.574 for 100 tests
Testing with a 1000*1000 grid area. Total time 521.210. Avg 5.212 for 100 tests
Testing with a 3000*3000 grid area. Total time 10113.633. Avg 101.136 for 100 tests
Текущая версия в среднем в 30-35 раз быстрее по сравнению с исходной реализацией.Таким образом, его вызов на данный момент прекращается.
FINAL UPDATE (протестировано на 8-ядерном компьютере с гиперпоточностью (больше нет локального хоста и больше нет сравнения между яблоками и яблоками) | Дальнейшие оптимизации, связанные с Cython, и кэшированиезначение y | Общий дополнительный прирост после ОБНОВЛЕНИЯ № 6 ~ 78% | Общий прирост по сравнению с исходным кодом ~ 99,3%):
Testing with a 50*50 grid area. Total time 0.498. Avg 0.005 for 100 tests
Testing with a 100*100 grid area. Total time 1.146. Avg 0.011 for 100 tests
Testing with a 500*500 grid area. Total time 22.856. Avg 0.229 for 100 tests
Testing with a 1000*1000 grid area. Total time 113.819. Avg 1.138 for 100 tests
Testing with a 3000*3000 grid area. Total time 2228.098ms. Avg 22.281 for 100 tests
Testing with a 10000*10000 grid area. Total time 29407.874ms. Avg 294.79 for 100 tests
Testing with a 20000*20000 grid area. Total time 157185.469ms. Avg 1571.855 for 100 tests