Здравствуйте, CoderMonkey, Вы писали:
I>>Какой рантайм — экспериментальный, ближе всего к нему будет наверное node 8.8.1 64, точнее не могу сказать. На самом деле уже не важно. И вот почему — я позапускал эту версию от 19го сентября на разных компах с разной производительностью и сортировка везде укладывается в 1600+- 200 мс.
CM>Надо же, какой магический рантайм. Скорость от железа вообще не зависит.
Правильно так — зависит не от абстрактного "железа", а от пропускной способности шины/памяти, о чем уже много раз говорилось. Ты наверняка сам собирал себе комп, раз "сэкономил" для такого процессора на хилой памяти. Ну может такой же "умелец" собирал конфигурацию.
Будешь смеяться, у тебя DDR3 и именно это объясняет эти полторы секунды. Почему в C# меньше — потому что C# не забивает шину лишними обращениями, в ём тупо косвенность раза в полтора-два ниже.
Именно отсюда получается результат 1600+- 200. Проц и кеш и определяют эти +-200мс тупо потому, что они намного быстрее узкого места — шины/памяти.
CM>Хотя нет, я в магию не верю. Так что вся магия наверняка заключается в каком-то очень особом способе измерения.
Смотри внимательно подчеркнутую часть:
— если сравнить версии нода от 6й до 9й, то внезапно окажется, что где то посередине перформанс _падает_ на сортировке, при чем значительно, около 15%.
— на имеющемся железе(разные компы) сортировка работает в районе 1600+-200мс. А вот инициализация от 2500 до 6500мс. node 8.8.1 64
Подчеркнутое говорит, что инициализация, в отличие от сортировки, очень сильно зависит от процессора, а они у нас тобой сильно разные.
Теперь очередная попа-боль для тебя:
http://rsdn.org/forum/flame.comp/6947971.1Автор: Ikemefula
Дата: 28.10.17
Замеры видишь ? Я их сюда скопирую, на всякий, если у тебя со зрением проблемы:
Init, miliseconds: 1598
Sort miliseconds: 1573
| Энергичная версия JS, длинные числа вместо GUID |
| 'use strict';
const N = 1000*1000;
const re = /-/g;
const arr = Array(N);
function Main(number) {
let watch = Date.now();
let vals = arr;
for(let i = 0; i<arr.length; i++) {
arr[i] = new TestClass();
}
let compare = (x, y) =>{
if(x === y)
return 0;
if(x > y)
return 1;
return -1;
};
console.warn(`Init, miliseconds: ${Date.now() - watch}`);
watch = Date.now();
QuickSort(vals, (x,y)=>compare(x.Id, y.Id));
console.warn(`Sort miliseconds: ${Date.now() - watch}`);
}
function QuickSort(vals, compare){
QuickSortImpl(vals, compare, 0, vals.length - 1);
}
function QuickSortImpl (vals, compare, left, right) {
if (right <= left)
return;
let i = left;
let j = right;
const mid = Math.floor((left + right) / 2);
const midVal = vals[mid];
while (i <= j) {
while (compare(vals[i], midVal) > 0) {
i++;
}
while (compare(vals[j], midVal) < 0) {
j--;
}
if (i <= j) {
const tmp = vals[i];
vals[i] = vals[j];
vals[j] = tmp;
i++;
j--;
}
}
if(left < i - 1) {
QuickSortImpl(vals, compare, left, i - 1);
}
if(right > i) {
QuickSortImpl(vals, compare, i, right);
}
}
class TestClass {
constructor() {
this.Id = CreateGuid();
this.Value = CreateGuid();
}
toString() {
return this.Id;
}
}
function ToArray(iterator) {
return [...iterator];
}
function* Range(start, end) {
for(let i = start; i<end; i++) {
yield i;
}
}
function* Select(iterator, projector) {
for(let x of iterator) {
yield projector(x);
}
}
function CreateGuid() {
let num = 0|Math.random() * Math.pow(10, 16);
return num.toString(16);
//return NewGuid().toString().replace(re, "");
}
function NewGuid() {
function s4() {
return (((1 + Math.random()) * 0x10000) & 0xFFFF).toString(16);
}
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
s4() + '-' + s4() + s4() + s4();
}
function delay(time) {
return new Promise((resolve)=>{
setTimeout(resolve, time);
});
}
for(let i = 0, promise = Promise.resolve(); i<100;i++) {
promise = promise.then(()=>Main(N)).then(()=>delay(1000));
}
|
| |
Здесь наблюдаем ровно ту же магию — сортировка каким то чудом держится в районе той же магической границы 1600+-200.
Вот еще два замера на том же хилом железе:
Init, miliseconds: 1163
Sort miliseconds: 1654
Init, miliseconds: 1306
Sort miliseconds: 1836
I>>Более того — даже разные рантаймы дают очень похожее число, колебания в пределах 15%.
CM>Разброс даже на том же самом железе и той же версии рантайма +-25%.
Если ты про разброс внутри серии, то это GC и потому я вывожу всю серию. Мне лень было считать среднее отклонение, дисперсию, матожидание и тд.
I>>Если мы про алгоритмы, то их принято доказывать, что они являются тем, что надо
CM>Элементарно, если тебе яйца танцевать мешают или еще какие проблемы подобного характера.
CM>Из 300 случайных тестовых наборов по миллиону записей, ноль ошибок. А теперь, вероятно, ты опять начнешь юлить и выкручиваться?
Хоть миллиард тестов по миллиону. Нужно доказать общий случай, а миллион — это ровно один. Студенты часто делают сорировку, которая работает, скажем, для четных или для тех, что делятся на 4 и тд.