Делает синтаксис инициализации набора C#, избегают инициализации по умолчанию наверху

Как Камарос предлагает , вы можете вызвать NSApplescript напрямую, без необходимости запуска отдельного процесса через NSTask (как CRGreen предлагает .)

код Swift

let myAppleScript = "..."
var error: NSDictionary?
if let scriptObject = NSAppleScript(source: myAppleScript) {
    if let output: NSAppleEventDescriptor = scriptObject.executeAndReturnError(
                                                                       &error) {
        print(output.stringValue)
    } else if (error != nil) {
        print("error: \(error)")
    }
}

7
задан Helen 15 September 2009 в 16:40
поделиться

4 ответа

Компилятор по-прежнему использует инструкцию IL newarr , поэтому CLR по-прежнему инициализирует массив.

Инициализация коллекции - просто магия компилятора - CLR ничего об этом не знает, поэтому все равно будет считать, что нужно выполнить очистку.

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

13
ответ дан 6 December 2019 в 07:27
поделиться

Быстрый тест:

        string[] arr1 =
        {
            "A","B","C","D"
        };
        arr1.GetHashCode();

        string[] arr2 = new string[4];
        arr2[0] = "A";
        arr2[1] = "B";
        arr2[2] = "C";
        arr2[3] = "D";

        arr2.GetHashCode();

приводит к этот IL (обратите внимание, они оба идентичны)

  IL_0002:  newarr     [mscorlib]System.String
  IL_0007:  stloc.2
  IL_0008:  ldloc.2
  IL_0009:  ldc.i4.0
  IL_000a:  ldstr      "A"
  IL_000f:  stelem.ref
  IL_0010:  ldloc.2
  IL_0011:  ldc.i4.1
  IL_0012:  ldstr      "B"
  IL_0017:  stelem.ref
  IL_0018:  ldloc.2
  IL_0019:  ldc.i4.2
  IL_001a:  ldstr      "C"
  IL_001f:  stelem.ref
  IL_0020:  ldloc.2
  IL_0021:  ldc.i4.3
  IL_0022:  ldstr      "D"
  IL_0027:  stelem.ref
  IL_0028:  ldloc.2
  IL_0029:  stloc.0
  IL_002a:  ldloc.0
  IL_002b:  callvirt   instance int32 [mscorlib]System.Object::GetHashCode()
  IL_0030:  pop
  IL_0031:  ldc.i4.4
  IL_0032:  newarr     [mscorlib]System.String
  IL_0037:  stloc.1
  IL_0038:  ldloc.1
  IL_0039:  ldc.i4.0
  IL_003a:  ldstr      "A"
  IL_003f:  stelem.ref
  IL_0040:  ldloc.1
  IL_0041:  ldc.i4.1
  IL_0042:  ldstr      "B"
  IL_0047:  stelem.ref
  IL_0048:  ldloc.1
  IL_0049:  ldc.i4.2
  IL_004a:  ldstr      "C"
  IL_004f:  stelem.ref
  IL_0050:  ldloc.1
  IL_0051:  ldc.i4.3
  IL_0052:  ldstr      "D"
  IL_0057:  stelem.ref
  IL_0058:  ldloc.1
  IL_0059:  callvirt   instance int32 [mscorlib]System.Object::GetHashCode()
10
ответ дан 6 December 2019 в 07:27
поделиться

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

Когда я переключился и создается со значениями по умолчанию, это занимает примерно такое же количество времени.

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

Создание экземпляра со значениями, отличными от значений по умолчанию:

            bool[] abPrimes = new[] { 
                true, true
            };
0000007e  mov         edx,2 
00000083  mov         ecx,79114A46h 
00000088  call        FD3006F0 
0000008d  mov         dword ptr [ebp-64h],eax 
00000090  mov         eax,dword ptr [ebp-64h] 
00000093  mov         dword ptr [ebp-54h],eax 
00000096  mov         eax,dword ptr [ebp-54h] 
00000099  cmp         dword ptr [eax+4],0 
0000009d  ja          000000A4 
0000009f  call        76A9A8DC 
000000a4  mov         byte ptr [eax+8],1 
000000a8  mov         eax,dword ptr [ebp-54h] 
000000ab  cmp         dword ptr [eax+4],1 
000000af  ja          000000B6 
000000b1  call        76A9A8DC 
000000b6  mov         byte ptr [eax+9],1 
000000ba  mov         eax,dword ptr [ebp-54h] 
000000bd  mov         dword ptr [ebp-40h],eax 

Создание экземпляра со значениями по умолчанию:

bool[] abPrimes2 = new[] { 
              false, false
            };
000000c0  mov         edx,2 
000000c5  mov         ecx,79114A46h 
000000ca  call        FD3006F0 
000000cf  mov         dword ptr [ebp-68h],eax 
000000d2  mov         eax,dword ptr [ebp-68h] 
000000d5  mov         dword ptr [ebp-54h],eax 
000000d8  mov         eax,dword ptr [ebp-54h] 
000000db  mov         dword ptr [ebp-5Ch],eax 
1
ответ дан 6 December 2019 в 07:27
поделиться

Невозможно избежать инициализации каждого слота массива значением по умолчанию, при минимум на уровне IL.

Строка - это КЛАСС, а не структура.

Это означает, что A, B, C, D и массив могут храниться в любом месте. A, B, C и D могут быть получены из внутреннего пула, что ссылка на объект может быть динамической.

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

PS. Преждевременная оптимизация - корень всех зол.

0
ответ дан 6 December 2019 в 07:27
поделиться
Другие вопросы по тегам:

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