I have a codebase in Delphi that heavily uses sets. Hence my interest in Oxygene. However, I have a penchant for efficiency, so I wrote a test in Oxygene and a test in RemObjects C# uses Flag enums, and then viewed the ASM for each.
Oxygene’s code is TEN TIMES LARGER than C#'s, and has multiple calls! Below, Oxygene followed by C#:
var s1: TSet := [SSet.sThree];
00000139 lea rcx,[5DF945D2h]
00000140 mov edx,1
00000145 call 000000005F6219F0
0000014a mov qword ptr [rsp+00000098h],rax
00000152 mov rax,qword ptr [rsp+00000098h]
0000015a mov qword ptr [rsp+000000A0h],rax
00000162 mov rax,qword ptr [rsp+000000A0h]
0000016a mov rax,qword ptr [rax+8]
0000016e mov qword ptr [rsp+000000A8h],0
0000017a cmp qword ptr [rsp+000000A8h],rax
00000182 jae 0000000000000196
00000184 mov rax,qword ptr [rsp+000000A8h]
0000018c mov qword ptr [rsp+000000A8h],rax
00000194 jmp 000000000000019B
00000196 call 000000005FB09660
0000019b mov rcx,qword ptr [rsp+000000A0h]
000001a3 mov rax,qword ptr [rsp+000000A8h]
000001ab mov byte ptr [rcx+rax+10h],4
000001b0 lea rcx,[00049D10h]
000001b7 call 000000005F621900
000001bc mov qword ptr [rsp+000000B0h],rax
000001c4 mov rax,qword ptr [rsp+000000B0h]
000001cc mov qword ptr [rsp+000000B8h],rax
000001d4 mov rdx,qword ptr [rsp+00000098h]
000001dc mov rcx,qword ptr [rsp+000000B8h]
000001e4 call FFFFFFFFFFEDC3C8
000001e9 mov r11,qword ptr [rsp+000000B8h]
000001f1 mov qword ptr [rsp+30h],r11
var s2 := [SSet.sOne, SSet.sThree];
000001f6 lea rcx,[0005391Ah]
000001fd mov edx,2
00000202 call 000000005F6219F0
00000207 mov qword ptr [rsp+000000C0h],rax
0000020f mov rax,qword ptr [rsp+000000C0h]
00000217 mov qword ptr [rsp+000000C8h],rax
0000021f mov rax,qword ptr [rsp+000000C8h]
00000227 mov rax,qword ptr [rax+8]
0000022b mov qword ptr [rsp+000000D0h],0
00000237 cmp qword ptr [rsp+000000D0h],rax
0000023f jae 0000000000000253
00000241 mov rax,qword ptr [rsp+000000D0h]
00000249 mov qword ptr [rsp+000000D0h],rax
00000251 jmp 0000000000000258
00000253 call 000000005FB09660
00000258 mov rcx,qword ptr [rsp+000000C8h]
00000260 mov rax,qword ptr [rsp+000000D0h]
00000268 mov dword ptr [rcx+rax*4+10h],0
00000270 mov rax,qword ptr [rsp+000000C0h]
00000278 mov qword ptr [rsp+000000D8h],rax
00000280 mov rax,qword ptr [rsp+000000D8h]
00000288 mov rax,qword ptr [rax+8]
0000028c mov qword ptr [rsp+000000E0h],1
00000298 cmp qword ptr [rsp+000000E0h],rax
000002a0 jae 00000000000002B4
000002a2 mov rax,qword ptr [rsp+000000E0h]
000002aa mov qword ptr [rsp+000000E0h],rax
000002b2 jmp 00000000000002B9
000002b4 call 000000005FB09660
000002b9 mov rcx,qword ptr [rsp+000000D8h]
000002c1 mov rax,qword ptr [rsp+000000E0h]
000002c9 mov dword ptr [rcx+rax*4+10h],2
000002d1 mov rax,qword ptr [rsp+000000C0h]
000002d9 mov qword ptr [rsp+38h],rax
var ix := s1 * s2;
000002de mov rax,qword ptr [rsp+30h]
000002e3 mov qword ptr [rsp+000000E8h],rax
000002eb mov rcx,qword ptr [rsp+38h]
000002f0 call FFFFFFFFFFEDC380
000002f5 mov qword ptr [rsp+000000F0h],rax
000002fd mov rdx,qword ptr [rsp+000000F0h]
00000305 mov rcx,qword ptr [rsp+000000E8h]
0000030d call FFFFFFFFFFEDC388
00000312 mov qword ptr [rsp+000000F8h],rax
0000031a mov rax,qword ptr [rsp+000000F8h]
00000322 mov qword ptr [rsp+40h],rax
if (SSet.sThree in ix) then
00000327 mov rdx,qword ptr [rsp+40h]
0000032c mov ecx,2
00000331 call FFFFFFFFFFEDC370
00000336 mov byte ptr [rsp+00000100h],al
0000033d movzx eax,byte ptr [rsp+00000100h]
00000345 test eax,eax
00000347 je 0000000000000363
var cs1: CSet := CSet.sThree;
00000363 mov dword ptr [rsp+48h],3
var cs2: CSet := CSet.sOne or CSet.sThree;
0000036b mov dword ptr [rsp+4Ch],3
var ix1 := cs1 and cs2;
00000373 mov ecx,dword ptr [rsp+4Ch]
00000377 mov eax,dword ptr [rsp+48h]
0000037b and eax,ecx
0000037d mov dword ptr [rsp+50h],eax
if (ix1 and CSet.sThree) <> 0 then
00000381 mov eax,dword ptr [rsp+50h]
00000385 and eax,3
00000388 test eax,eax
0000038a je 00000000000003A6
Could someone from RemObjects comment on this please.