Как Камарос предлагает , вы можете вызвать 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)")
}
}
Компилятор по-прежнему использует инструкцию IL newarr
, поэтому CLR по-прежнему инициализирует массив.
Инициализация коллекции - просто магия компилятора - CLR ничего об этом не знает, поэтому все равно будет считать, что нужно выполнить очистку.
Однако это должно быть очень, очень быстро - это просто стирает память. Я сомневаюсь, что во многих ситуациях это значительные накладные расходы.
Быстрый тест:
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()
Я провел небольшой тест по созданию экземпляра массива с использованием описанного вами синтаксиса и обнаружил, что создание экземпляра с нестандартными значениями заняло примерно в 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
Невозможно избежать инициализации каждого слота массива значением по умолчанию, при минимум на уровне IL.
Строка - это КЛАСС, а не структура.
Это означает, что A, B, C, D и массив могут храниться в любом месте. A, B, C и D могут быть получены из внутреннего пула, что ссылка на объект может быть динамической.
Но я считаю, что JIT могла бы достаточно умен, чтобы уменьшить половину этих накладных расходов.
PS. Преждевременная оптимизация - корень всех зол.