Найдите длину массива JavaScript без удаленных объектов

Если Вы хотите стать немного более техническими о том, что энергозависимое ключевое слово делает, рассматривает следующей программой (я использую DevStudio 2005):

#include <iostream>
void main()
{
  int j = 0;
  for (int i = 0 ; i < 100 ; ++i)
  {
    j += i;
  }
  for (volatile int i = 0 ; i < 100 ; ++i)
  {
    j += i;
  }
  std::cout << j;
}

Используя оптимизированный стандарт (выпускают) параметры компилятора, компилятор создает следующий ассемблер (IA32):

void main()
{
00401000  push        ecx  
  int j = 0;
00401001  xor         ecx,ecx 
  for (int i = 0 ; i < 100 ; ++i)
00401003  xor         eax,eax 
00401005  mov         edx,1 
0040100A  lea         ebx,[ebx] 
  {
    j += i;
00401010  add         ecx,eax 
00401012  add         eax,edx 
00401014  cmp         eax,64h 
00401017  jl          main+10h (401010h) 
  }
  for (volatile int i = 0 ; i < 100 ; ++i)
00401019  mov         dword ptr [esp],0 
00401020  mov         eax,dword ptr [esp] 
00401023  cmp         eax,64h 
00401026  jge         main+3Eh (40103Eh) 
00401028  jmp         main+30h (401030h) 
0040102A  lea         ebx,[ebx] 
  {
    j += i;
00401030  add         ecx,dword ptr [esp] 
00401033  add         dword ptr [esp],edx 
00401036  mov         eax,dword ptr [esp] 
00401039  cmp         eax,64h 
0040103C  jl          main+30h (401030h) 
  }
  std::cout << j;
0040103E  push        ecx  
0040103F  mov         ecx,dword ptr [__imp_std::cout (40203Ch)] 
00401045  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (402038h)] 
}
0040104B  xor         eax,eax 
0040104D  pop         ecx  
0040104E  ret              

Рассмотрение вывода, компилятор решил использовать регистр ecx для хранения значения j переменной. Для энергонезависимого цикла (первое) компилятор присвоил меня регистру eax. Довольно простой. Существует несколько интересных битов, хотя - lea ebx, [ebx] инструкция является эффективно многобайтовой инструкцией по NOP так, чтобы переходы цикла к 16 байтам выровняли адрес памяти. Другой использование edx для постепенного увеличения счетчика цикла вместо того, чтобы использовать inc eax инструкция. Добавление reg, reg инструкция имеет более низкую задержку на нескольких ядрах IA32 по сравнению с inc reg инструкция, но никогда не имеет более высокую задержку.

Теперь для цикла с энергозависимым счетчиком цикла. Счетчик хранится в [ESP], и энергозависимое ключевое слово говорит компилятору, что значение должно всегда читаться из к памяти и никогда не присваиваться регистру. Компилятор даже идет, насколько не сделать загрузку/инкремент/хранилище как три отличных шага (загрузите eax, inc eax, сохраните eax) при обновлении встречного значения вместо этого память непосредственно изменяется в единственной инструкции (добавить мадам, reg). Путем код был создан, гарантирует, что значение счетчика цикла всегда актуально в контексте единственного ядра процессора. Никакая операция на данных не может привести к повреждению или потере данных (следовательно не использующий load/inc/store, так как значение может измениться во время inc, таким образом потерянного на хранилище). Так как прерывания могут только быть обслужены, как только текущая команда завершилась, данные никогда не могут повреждаться, даже с невыровненной памятью.

, Как только Вы представляете второй ЦП системе, энергозависимое ключевое слово не примет меры против данных, обновляемых другим ЦП одновременно. В вышеупомянутом примере Вам были бы нужны данные, которые будут не выровнены для получения потенциального повреждения. Энергозависимое ключевое слово не предотвратит потенциальное повреждение, если данные не могут быть обработаны атомарно, например, если бы счетчик цикла имел тип, долго длинный (64 бита) тогда, то это потребовало бы два 32 битовых операции обновлять значение, посреди которого прерывание может произойти и изменить данные.

Так, энергозависимое ключевое слово только хорошо для выровненных данных, которые меньше чем или равны размеру собственных регистров, таким образом, что операции являются всегда атомарными.

энергозависимое ключевое слово было задумано, чтобы использоваться с операциями IO, где IO будет постоянно изменять, но имел базовый адрес, такой как устройство UART с отображенной памятью, и компилятор не должен продолжать снова использовать первое значение, считанное из адреса.

, Если Вы обрабатываете большие данные или имеете несколько центральных процессоров тогда, Вам будет нужен более высокий уровень (ОС) запирающая система для обработки доступа к данным правильно.

5
задан Lobe 15 October 2009 в 04:36
поделиться

2 ответа

Я думаю, что вы удаляете элементы массива с помощью оператора delete .

Этот оператор удаляет элемент по указанному вами индексу, но длина массива не изменяется, например:

var a = [1,2,3];

delete a[0];

console.log(a); // results in [undefined, 2, 3] 

Если вы хотите удалить элементы и сдвинуть индексы, вы можете использовать функцию splice :

var a = [1,2,3];

a.splice(0,1);

console.log(a); // [2, 3]

Вы можете реализовать простую функцию для удаления элементов в заданный индекс:

Array.prototype.removeAt = function (index) {
  this.splice(index,1);
};
13
ответ дан 18 December 2019 в 09:50
поделиться

Джон Ресиг (автор jQuery) написал функцию, которая (действительно) удаляет элементы из массива в Javascript. Если вы используете эту функцию вместо оператора удаления, вы должны получить точное количество из массива после удаления.

http://ejohn.org/blog/javascript-array-remove/

1
ответ дан 18 December 2019 в 09:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: