Autor Beitrag
Spaceguide
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 552


(D3/D7/D8) Prof.
BeitragVerfasst: Fr 10.06.05 11:24 
Ich bin gerade dabei ein Projekt aufzuräumen. Dabei möchte ich die ganzen alten "unsafe" Typen und Aufrufe durch
neue ersetzten.

1) PByteArray mit GetMem/FreeMem

Ich glaube ein array of byte mit SetLength(array,Länge) zum Alloziieren und SetLength(array,0) zum Freigeben ist das korrekte Substitut. Was mache ich, wenn ich ein array mit Low(array) < 0 haben möchte?

Die Übergabe als Parameter sollte von a : PByteArray durch var a : array of byte ersetzt werden, das dürfte den gleichen Effekt haben, oder?

Was mache ich, wenn ich auf ein array of byte zeigen möchte? Geht das dann überhaupt ohne Kapselung in einer Klasse? Mit Pointern bin ich ja wieder bei meinem "unsafe" Problem angelangt.

2) PChar

Das ist ziemlich schlecht zu ersetzen, da die Windows-API diesen Typ doch noch recht häufig erwartet und ich auch keine Ahnung habe, wie ich ansonsten einen String an externe DLLs von anderen Sprachen übergeben kann.

3) Assembler

Da muss ich wohl Adé zu den SSE-optimierten Move und FillChar sagen, welche 2x so schnell waren :(
retnyg
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2754

SNES, GB, GBA, CPC, A500, 486/66, P4/3.0HT: NintendOS, AmigaOS, DoS
Delphi 5, Delphi 7
BeitragVerfasst: Fr 10.06.05 11:44 
:gruebel:
hast du ein problem mit schnellem code ?

_________________
es gibt leute, die sind genetisch nicht zum programmieren geschaffen.
in der regel haben diese leute die regel...
Spaceguide Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 552


(D3/D7/D8) Prof.
BeitragVerfasst: Fr 10.06.05 12:01 
Nein, aber wenn's irgendwann mal Richtung .NET gehen soll, muss das raus.
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Fr 10.06.05 19:52 
@ASM: Jetzt kennst Du einen grund, warum ich .NET hasse. Es behindert den Programmierer daran, das zu tun, was für seinen Algo das beste ist.

@PChar: Abändern in PAnsiChar AFAIK.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Sa 11.06.05 13:09 
user profile iconBenBE hat folgendes geschrieben:
@ASM: Jetzt kennst Du einen grund, warum ich .NET hasse. Es behindert den Programmierer daran, das zu tun, was für seinen Algo das beste ist.

@PChar: Abändern in PAnsiChar AFAIK.
Nun ja, es soll ja platformübergreifend sein. Wer in .NET unsafe programmieren will, kann ja. Muss man einfach als unsafe deklarieren, soweit ich weiss.

PChar ist soweit ich weiss ein Synonym für PAnsiChar; genau wie String dasselbe wie AnsiString ist. Weiss allerdings nicht, ob das unter .NET auch noch dasselbe ist.

user profile iconSpaceguide hat folgendes geschrieben:
1) PByteArray mit GetMem/FreeMem

Ich glaube ein array of byte mit SetLength(array,Länge) zum Alloziieren und SetLength(array,0) zum Freigeben ist das korrekte Substitut.
Oder allgemeiner: Finalize(myarray)

user profile iconSpaceguide hat folgendes geschrieben:
Was mache ich, wenn ich ein array mit Low(array) < 0 haben möchte?
Geht bei dynamischen Arrays nicht. Dann musst du die Indizes selbst umrechnen.

user profile iconSpaceguide hat folgendes geschrieben:
Die Übergabe als Parameter sollte von a : PByteArray durch var a : array of byte ersetzt werden, das dürfte den gleichen Effekt haben, oder?
Mit dem Unterschied, dass du in der Prozedur zusätzlich noch die Grösse des Arrays abfragen kann (weswegen der Prozeduraufruf auch langsamer wird).

user profile iconSpaceguide hat folgendes geschrieben:
Was mache ich, wenn ich auf ein array of byte zeigen möchte? Geht das dann überhaupt ohne Kapselung in einer Klasse? Mit Pointern bin ich ja wieder bei meinem "unsafe" Problem angelangt.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
var
 A, B: array of Byte;
begin
 SetLength(A, 1);
 A[0] := 20;
 B := A;
 B[0] := 12;
 // A[0] ist jetzt auch 12
end;

user profile iconSpaceguide hat folgendes geschrieben:
2) PChar

Das ist ziemlich schlecht zu ersetzen, da die Windows-API diesen Typ doch noch recht häufig erwartet und ich auch keine Ahnung habe, wie ich ansonsten einen String an externe DLLs von anderen Sprachen übergeben kann.
Ich würde meinen, dass man die "alten" APIs unter .NET nicht mehr benötigt, sondern .NET eigene Funktionen zur Verfügung stellt. Hab leider noch nie mit .NET gearbeitet, aber wenn die PChars dort Probleme bereiten sollten, gibt es sicher einen Umweg.

user profile iconSpaceguide hat folgendes geschrieben:
3) Assembler

Da muss ich wohl Adé zu den SSE-optimierten Move und FillChar sagen, welche 2x so schnell waren :(
Wenn du platformunabhängig sein willst, ja. Jedoch würd ich erwarten, dass .NET sowas wie MemCopy, ZeroMemory usw. zur Verfügung stellt, welche auf einem gegebenen System am schnellsten läuft.

Aber am Elegantesten wäre es natürlich, wenn du strikt objektorientiert programmieren würdest. Das heisst keine Arrays mehr sondern Klassen. Wenn dir die Geschwindigkeit wichtig ist, dann ist .NET ohnehin nicht die ideale Lösung.
Spaceguide Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 552


(D3/D7/D8) Prof.
BeitragVerfasst: Sa 11.06.05 21:41 
user profile icondelfiphan hat folgendes geschrieben:

PChar ist soweit ich weiss ein Synonym für PAnsiChar; genau wie String dasselbe wie AnsiString ist. Weiss allerdings nicht, ob das unter .NET auch noch dasselbe ist.


Strings sind ja in .NET hoffentlich threadsafe, kann ich die wieder benutzen. ;-)

Zitat:

user profile iconSpaceguide hat folgendes geschrieben:
Was mache ich, wenn ich ein array mit Low(array) < 0 haben möchte?
Geht bei dynamischen Arrays nicht. Dann musst du die Indizes selbst umrechnen.


Aua, nicht sehr elegant.

Zitat:
user profile iconSpaceguide hat folgendes geschrieben:
Die Übergabe als Parameter sollte von a : PByteArray durch var a : array of byte ersetzt werden, das dürfte den gleichen Effekt haben, oder?
Mit dem Unterschied, dass du in der Prozedur zusätzlich noch die Grösse des Arrays abfragen kann (weswegen der Prozeduraufruf auch langsamer wird).


Ist es wirklich langsamer? Ein SetLength mit Bytes auf 1000 holt sich 1008 Byte. Die Länge des Arrays kann ja am Anfang der Array-Daten stehen. Es dürfte also ausreichen, nur den Zeiger auf den Stack zu schieben.

Zitat:

Aber am Elegantesten wäre es natürlich, wenn du strikt objektorientiert programmieren würdest. Das heisst keine Arrays mehr sondern Klassen. Wenn dir die Geschwindigkeit wichtig ist, dann ist .NET ohnehin nicht die ideale Lösung.


Gibt es etwas wie eine Array-Klasse, vom lahmen TList mal abgesehen?

Danke für deine kompetente Hilfe.
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Sa 11.06.05 22:05 
user profile iconSpaceguide hat folgendes geschrieben:
Ist es wirklich langsamer? Ein SetLength mit Bytes auf 1000 holt sich 1008 Byte. Die Länge des Arrays kann ja am Anfang der Array-Daten stehen. Es dürfte also ausreichen, nur den Zeiger auf den Stack zu schieben.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
procedure processA(var a: array of Byte);
begin
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 a: array of Byte;
begin
 processA(a);
end;


Der Prozeduraufruf sieht so aus:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
 mov eax,[ebp-$04]
 call @DynArrayHigh
 mov edx,eax
 mov eax,[ebp-$04]
 call processA
retnyg
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2754

SNES, GB, GBA, CPC, A500, 486/66, P4/3.0HT: NintendOS, AmigaOS, DoS
Delphi 5, Delphi 7
BeitragVerfasst: Sa 11.06.05 22:10 
habe da zum thema .net grade was interessantes gefunden: www.sysinternals.com/Blog/ - unterster artikel.
da wird speicher und cpu verbrauch eines managed und unmanaged notepad verglichen...

_________________
es gibt leute, die sind genetisch nicht zum programmieren geschaffen.
in der regel haben diese leute die regel...
Spaceguide Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 552


(D3/D7/D8) Prof.
BeitragVerfasst: So 12.06.05 17:00 
user profile icondelfiphan hat folgendes geschrieben:

Der Prozeduraufruf sieht so aus:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
 mov eax,[ebp-$04]
 call @DynArrayHigh
 mov edx,eax
 mov eax,[ebp-$04]
 call processA



Erstaunlich, und das ist ziemlich ineffizient, hab das grad mal getestet. Ein statisches Array bzw. PByteArray ist bei einer fast leeren Prozedur um Faktor 5 schneller. Packe ich das dynamische Array allerdings in eine Klasse und übergebe die, dann ist das ganze in etwa genausoschnell wie ein PByteArray :).