You are not logged in.
Pages: 1
I want to learn your great mORMot framework. Could you help to comment on the three questions below ?
procedure TForm1.FormCreate(Sender: TObject);
type
TGroup = array of Integer;
var
Group: TGroup;
GroupA: TDynArray;
I, V: Integer;
Test: RawByteString;
begin
GroupA.Init(TypeInfo(TGroup),Group);
for I := 0 to 1000 do
begin
//GroupA.Add(I); // Question 1: Why "I" is not used directly ? (Page 85 of doc v1.18 says "need argument passed as a const variable". However, I do not understand what bad effects will come otherwise.)
V := I ;
GroupA.Add(V); // Question 2: TDynArray does not have type-check ? It seems anything can be added here, which is not alerting enough ?
end;
Test := GroupA.SaveTo;
GroupA.Clear;
//GroupA.LoadFrom(Test); // Question 3: This line (from Page 86) does not compile ? Should one hard-case as below ?
GroupA.LoadFrom(PAnsiChar(Test));
Caption := FloatToStrF(Group[50], ffFixed, 12, 6);
end;
Offline
All this is not tied to the library, but to how "untyped" const/var parameters work.
1. I suppose in this case, you can use I directly, since I is a variable.
What you can't do e.g. is to pass a constant, like 'a string' or 3.14159: it won't compile.
2. There is NO type-check with "untyped" const/var parameters.
By design (this is a limitation of it).
As a workaround, we may use a generic-based method type, but code size will increase a lot: so in this case, you can just use TArray<>.
But of course, you will miss the most advanced methods of TDynArray, and TArray<> will in fact STORE the array, whereas TDynArray will just be a wrapper to access an external dynamic array variable.
3. LoadFrom() method uses a pointer, since it is iterative: it returns the position after the read buffer, so allows to load several content in the same memory buffer.
You should use indeed either LoadFrom(PAnsiChar(Test)) or even LoadFrom(pointer(Test)) to use it.
Offline
Thank you for your helpful comments very much !
Offline
Could you help to comment on another two questions of mine ?
1.
On Page 87 of Doc v1.18, "4.3.3 Capacity handling via an external Count", it is mentioned that "That is, whether you call Add or Delete methods, an internal call to SetLength(DynArrayVariable) is performed.". I am wondering, does the dynamic array grow by 1 or exponentially every time ?
2.
Your unitary tests are not contained in the "nightly" zip file. I wonder where to download them ? (For example, 4.3.5 on Page 87 mentions TTestLowLevelCommon where one could learn how to use TDynArray/TDynArrayHashed.) (Found in "SynSelfTests.pas". )
Last edited by ComingNine (2014-04-28 12:44:39)
Offline
1. The array length is used as capacity, the array count is stored in the external Count integer variable.
Add/Delete let the array grow by an exponential value, not by 1 (which would not increase the speed).
See how procedure TDynArray.SetCount(aCount: integer) is implemented:
capa := DynArrayLength(Value^);
if delta>0 then begin
// size-up -> grow by chunks
if capa>=fCountP^ then
exit; // no need to grow
inc(capa,capa shr 2);
if capa<fCountP^ then
aCount := fCountP^ else
aCount := capa;
end else
// size-down -> only if worth it (for faster Delete)
if (capa<=MINIMUM_SIZE) or (capa-aCount<capa shr 3) then
exit;
You can also use TDynArray.SetCapacity(aCapacity: integer) if you want to define the dynamic array capacity before any Add().
2. AFAIK SynSelfTests.pas is included in the nightly zip file... OK you did find it.
Offline
Thank you very much for your knowledgeable comments !
Offline
Pages: 1