ar0*_*968 1 delphi asynchronous
我需要填充TJsonArray很多TJsonObject(TJsonArray并且TJsonObject来自JsonDataObjects)。我正在尝试TParallel.For()从本System.Threading机提高性能,但是我TParallel.For()的速度比经典for循环慢。
这是我的测试代码:
var
aLock: TCriticalSection;
jItems: TJsonArray;
jItem: TJsonObject;
aStart: Cardinal;
aEnd: Cardinal;
i: integer;
begin
// array of json objects
jItems := TJsonArray.Create;
// ASYNC FOR LOOP
// ----------------------------
aLock := TCriticalSection.Create;
aStart := GetTickCount;
TParallel.&For(0, 10000000,
procedure(k: Integer)
var
xItem: TJsonObject;
begin
aLock.Enter;
try
// add new object to the array
xItem := jItems.AddObject;
finally
aLock.Leave;
end;
// populate some object property for test
xItem.I['I'] := k; // .I for integer
xItem.F['F'] := k; // .F for float
xItem.S['S'] := IntToStr(k); // .S for string
xItem.D['D'] := Now; // .D for date
end
);
aEnd := GetTickCount;
Writeln('ASYNC ', aEnd-aStart);
// ----------------------------
aLock.Free;
jItems.Clear;
// SYNC FOR LOOP
// ----------------------------
aStart := GetTickCount;
for i := 0 to 10000000 do begin
jItem := jItems.AddObject;
jItem.I['I'] := i;
jItem.F['F'] := i;
jItem.S['S'] := IntToStr(i);
jItem.D['D'] := Now;
end;
aEnd := GetTickCount;
Writeln('SYNC ', aEnd-aStart);
// ----------------------------
jItems.Free;
end;
Run Code Online (Sandbox Code Playgroud)
这是结果(数字是经过的时间(以毫秒为单位)):
我认为我的TParallel.For()实现是错误的。我究竟做错了什么?
正如其他人提到的那样,您在TJsonArray序列化周围使用关键部分会使线程线程化,并且可能是主要的瓶颈。尝试摆脱关键部分,在进入循环之前预先分配阵列,然后让每次循环迭代都根据需要简单地填充阵列的现有插槽。这样,您就更有机会同时并行地将多个对象插入到阵列中。
var
jItems: TJsonArray;
jItem: TJsonObject;
aStart: Cardinal;
aEnd: Cardinal;
i: integer;
begin
// array of json objects
jItems := TJsonArray.Create;
// ASYNC FOR LOOP
// ----------------------------
jItems.Count := 10000001; // <-- add this!
aStart := GetTickCount;
TParallel.&For(0, 10000000,
procedure(k: Integer)
var
xItem: TJsonObject;
begin
// create new object
xItem := TJsonObject.Create;
// populate some object property for test
xItem.I['I'] := k; // .I for integer
xItem.F['F'] := k; // .F for float
xItem.S['S'] := IntToStr(k); // .S for string
xItem.D['D'] := Now; // .D for date
// add new object to the array
jItems.O[k] := xItem;
end
);
aEnd := GetTickCount;
Writeln('ASYNC ', aEnd-aStart);
// ----------------------------
jItems.Clear;
// SYNC FOR LOOP
// ----------------------------
aStart := GetTickCount;
for i := 0 to 10000000 do begin
jItem := jItems.AddObject;
jItem.I['I'] := i;
jItem.F['F'] := i;
jItem.S['S'] := IntToStr(i);
jItem.D['D'] := Now;
end;
aEnd := GetTickCount;
Writeln('SYNC ', aEnd-aStart);
// ----------------------------
jItems.Free;
end;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
248 次 |
| 最近记录: |