Forum: Projekte & Code [C] Strings schnell zusammensetzen


von B. S. (bestucki)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,
Mein Projekt hat schon wieder Output generiert. strcat aus string.h war 
mir zu langsam, da hab ich ein paar Zeilen Code geschrieben. Vielleicht 
kanns ja jemand gebrauchen.

Die Bibliothek (wenn man das bereits so nennen darf) ist dazu da, um 
mehrere Strings und/oder Zeichen zu einem String zusammenzuführen.

Konstruktive Kritik und Verbesserungsvorschläge sind stets willkommen.

von Peter II (Gast)


Lesenswert?

naja, mit der Static variable ist das ding eigentlich kaum zu verwenden
und extrem riskant.

Somal in der Doku dieser wichtige Punkt nicht ordentlich hervorgehoben 
ist.

Man kann also nur einen sting im ganzen Programm damit bearbeiten. 
Sinnvoller ist wohl eine Struct aus aus String und länge als eigenen 
Datentype anzulegen.

von B. S. (bestucki)


Lesenswert?

Danke für deine Antwort.

Peter II schrieb:
> naja, mit der Static variable ist das ding eigentlich kaum zu verwenden
> und extrem riskant.
Ja es ist riskant, man muss einfach wissen was man tut. Ich könnte 
natürlich noch eine maximale Länge einführen, welche mit SGnew definiert 
werden könnte. So könnte man wenigstens den RAM nicht zerschiessen. Aber 
warum kaum zu verwenden? Fürs Hobby sollte es reichen.

Peter II schrieb:
> Man kann also nur einen sting im ganzen Programm damit bearbeiten.
> Sinnvoller ist wohl eine Struct aus aus String und länge als eigenen
> Datentype anzulegen.
Natürlich kannst du mehrere Strings in einem Programm bearbeiten, du 
musst einfach SGnew nochmals aufrufen und den Zeiger für den neuen 
String übergeben.

von Peter II (Gast)


Lesenswert?

be stucki schrieb:
> Peter II schrieb:
>> Man kann also nur einen sting im ganzen Programm damit bearbeiten.
>> Sinnvoller ist wohl eine Struct aus aus String und länge als eigenen
>> Datentype anzulegen.
> Natürlich kannst du mehrere Strings in einem Programm bearbeiten, du
> musst einfach SGnew nochmals aufrufen und den Zeiger für den neuen
> String übergeben.

weil man keine unterfunktionen nach SGnew aufrufen darf, denn diese 
könnte ja wieder selber SGnew aufrufen. in größere programm weiss man 
das nicht immer bzw. es wird erst später eingebaut.

Und wenn ich es nur in einem 3 Zeiler verwenden kann, dann kann ich es 
auch gleich von Hand mache dann ist es sogar schneller weil die 
umständlichen funktionsaufrufe wegfallen.

von Sven P. (Gast)


Lesenswert?

be stucki schrieb:
> Hallo zusammen,
> Mein Projekt hat schon wieder Output generiert. strcat aus string.h war
> mir zu langsam

Hast mal erforscht, weshalb strcat so langsam ist?

von Peter II (Gast)


Lesenswert?

Sven P. schrieb:
> be stucki schrieb:
>> Hallo zusammen,
>> Mein Projekt hat schon wieder Output generiert. strcat aus string.h war
>> mir zu langsam
> Hast mal erforscht, weshalb strcat so langsam ist?

das ist doch klar. Er bestimmt jedesmal das ende vom ersten String.

von Peter D. (peda)


Lesenswert?

be stucki schrieb:
> strcat aus string.h war
> mir zu langsam

Eine spannende Frage ist, wozu zu langsam?

Stringoperationen nimmt man ja eigentlich nur zur Kommunikation mit dem 
Menschen und dazu kann es nicht langsam genug sein.

Ich habe in meinen Programmen immer einen extra Task, der dafür sorgt, 
daß Ausgaben nicht zu schnell erfolgen, damit sie den Betrachter nicht 
nerven. 200..500ms Delay ist ein ergonomischer Wert.

von B. S. (bestucki)


Lesenswert?

Peter II schrieb:
> weil man keine unterfunktionen nach SGnew aufrufen darf, denn diese
> könnte ja wieder selber SGnew aufrufen. in größere programm weiss man
> das nicht immer bzw. es wird erst später eingebaut.
Da hast du natürlich recht. So weit habe ich gar nicht gedacht, weil ich 
die Funktionen nur in einer einzigen Funktion verwende.

Peter Dannegger schrieb:
> Eine spannende Frage ist, wozu zu langsam?
Das Problem ist, dass der Controller in meinem aktuellen Projekt jede 
Menge zu tun hat, da Spielt es schon eine Rolle, ob er dafür 40ms oder 
nur 500us benötigt. Zusätzlich wird das Zusammensetzen durch Interrupts 
und wichtigere Tasks unterbrochen, so dass das Zusammensetzen meines 
Strings länger als 100ms dauert. Und da noch mehr Aufgaben hinzukommen 
werden, beginne ich dort mit den Optimierungen, wo die meiste Zeit 
verbraten wird und das war nunmal hier. Aber das ist wieder ein anderes 
Thema, es gibt noch viel zu tun.


Vielen Dank für die Kritik. Ich werde die Sache neu aufbauen und eine 
Bibliothek schreiben, die auch brauchbar ist.

von Peter II (Gast)


Lesenswert?

be stucki schrieb:
> Das Problem ist, dass der Controller in meinem aktuellen Projekt jede
> Menge zu tun hat, da Spielt es schon eine Rolle, ob er dafür 40ms oder
> nur 500us benötigt. Zusätzlich wird das Zusammensetzen durch Interrupts
> und wichtigere Tasks unterbrochen, so dass das Zusammensetzen meines
> Strings länger als 100ms dauert. Und da noch mehr Aufgaben hinzukommen
> werden, beginne ich dort mit den Optimierungen, wo die meiste Zeit
> verbraten wird und das war nunmal hier. Aber das ist wieder ein anderes
> Thema, es gibt noch viel zu tun.

das macht mich neugierig, aber ich vermute mal das man das konzept 
überarbeiten kann und damit mehr zeit sparen als an solchen kleinigkeit 
wie strcat. Somal wir hier nicht von String mit 1Mbyte länge reden 
sondern von ein paar zeichen.

von B. S. (bestucki)


Lesenswert?

Peter II schrieb:
> das macht mich neugierig, aber ich vermute mal das man das konzept
> überarbeiten kann und damit mehr zeit sparen als an solchen kleinigkeit
> wie strcat. Somal wir hier nicht von String mit 1Mbyte länge reden
> sondern von ein paar zeichen.
Dass mein insgesamt 44 Zeichen langer String so lange benötigt um 
zusammengewerkelt zu werden, hätte ich auch nicht gedacht. Das Konzept 
könnte sicher verbessert werden. In meiner Hardware sind SD-Karte, 
externe AD-Wandler, Grafikdisplay, 2x RS232, RS485, 2x 8Bit parallele 
Schnittstelle und diverser Kleinkram vorhanden. In der SW diverse 
Filter, natürlich Treiber für die Hardware, Function String Parser, 
dynamische Speicherverwaltung, erstellen und ausgeben von Diagrammen auf 
dem Display um so das Gröbste zu nennen. Bei 5MHz internem Takt ist halt 
irgendeinmal Schluss (werde ich wahrscheinlich noch aufbohren müssen). 
Aber wie gesagt, das ist wieder ein anderes Thema. Falls ich irgendwo 
nicht weiter komme, werde ich bestimmt einen neuen Beitrag eröffnen. 
Keine Angst.

von Peter D. (peda)


Lesenswert?

be stucki schrieb:
> so dass das Zusammensetzen meines
> Strings länger als 100ms dauert.

Also die 100ms kann ich Dir nicht glauben, das sind ja Ewigkeiten.
Hast Du mal ein Beispielprogramm, was 100ms braucht?

Das Nadelöhr ist auf keinen Fall die String-Lib.
Ich vermute mal die SD-Karte oder die Grafik-Lib.

von F. F. (foldi)


Lesenswert?

Peter Dannegger schrieb:
> Ich vermute mal die SD-Karte oder die Grafik-Lib.

Was mit einer schnellen Karte ganz einfach getestet werden kann.

von B. S. (bestucki)


Lesenswert?

Vielen Dank für die rege Anteilnahme!
Gestern Nacht hab ich bereits eine neue Bibliothek geschrieben, die 
keine Static-Variable benutzt, sondern einen eigenen Datentyp. Dadurch 
sollte die Sache dann auch brauchbar sein.

Peter Dannegger schrieb:
> Also die 100ms kann ich Dir nicht glauben, das sind ja Ewigkeiten.
> Hast Du mal ein Beispielprogramm, was 100ms braucht?
Bin gerade nicht zu Hause, werde heute Abend ein Bespielprogramm 
schreiben und die Ausführungszeit messen. Ausserdem denötigt das 
Zusammensetzen ca. 40ms, es werden jedoch 100ms daraus, da es durch 
wichtigere Tasks unterbrochen wird. Und da noch weitere Tasks dazukommen 
werden, muss ich Rechenzeit sparen (steht bereits irgendwo weiter oben).

Peter Dannegger schrieb:
> Das Nadelöhr ist auf keinen Fall die String-Lib.
> Ich vermute mal die SD-Karte oder die Grafik-Lib.
SD-Karte glaub ich nicht. Läuft alles über Hardware-SPI und Interrupts:
Byte ist Register kopieren, Hauptprogramm weiter abarbeiten, wenn das 
Byte gesendet wurde gibts ein Interrupt und das nächste Byte wird in 
Register kopiert, usw. So wie ich das eingentlich immer mache.
Über die Grafik-Lib. kann ich im Moment keine Aussage machen, ich 
verwende, ausser in einer speziellen Ansicht, momentan nur den Textmodus 
und der geht ratz fatz.

Ich werde mich heute Abend (spät) wieder melden.

von 123 (Gast)


Lesenswert?

Wieso das ganze nicht als macro definieren? verhindert ggf stack 
operationen.

von Peter D. (peda)


Lesenswert?

be stucki schrieb:
> Dass mein insgesamt 44 Zeichen langer String so lange benötigt um
> zusammengewerkelt zu werden

44 Zeichen zu basteln darf weder 40ms noch 100ms brauchen, ich würde 
<44µs als real ansetzen.
Oder da ist noch ne sprintf-lib mit float Ausgabe benutzt, dann könnte 
schon 1ms zusammen kommen.

be stucki schrieb:
> SD-Karte glaub ich nicht. Läuft alles über Hardware-SPI und Interrupts:

Wieviel Byte puffert Dein HW-SPI?
Bei hohen Taktfrequenzen ist es oft das ganze 
Interrupt-Prolog/Epilog-Gedöns deutlich teuer, als 2µs (bei 4MHz Takt) 
auf das Ende des SPI zu pollen.
Und die SD hat ja auch interne Power-Up und Schreibzyklen, auf die 
gewartet werden muß. Daher sollte man möglichst große Blöcke schreiben. 
Nur byteweise wäre der Super-Gau.

be stucki schrieb:
> momentan nur den Textmodus
> und der geht ratz fatz.

Täusche Dich nicht, hast Du mal konkrete Zahlen (µs je Zeichen). Große 
Zeichen dauern auch deutlich länger (mehr Pixel) als 5*7.
Man sollte daher nicht zu häufig auf das LCD schreiben, alle 200ms ist 
ein ergonomischer Wert.

von B. S. (bestucki)


Lesenswert?

Ich bin gestern nicht mehr dazu gekommen zu posten.

Ich habe das Problem gelöst. Der Compiler hat für die 
string.h-Funktionen die falschen Sourcefiles verwendet. Diese waren 
meiner Meinung nach unnötig aufgebläht und benutzten wide chars. Wieder 
die originalen von Microchip runtergeladen und nun funzt das Ding wies 
sollte. Für das Zusammensetzen von insgesamt 12 kurzen Strings und drei 
einzelnen Zeichen zu einem String von 44 Zeichen Länge benötigen die 
Standardfunktionen nun ca. 1.2ms (bei 5MHz internem Takt).

Peter Dannegger schrieb:
> Wieviel Byte puffert Dein HW-SPI?
1 Byte

> Bei hohen Taktfrequenzen ist es oft das ganze
> Interrupt-Prolog/Epilog-Gedöns deutlich teuer, als 2µs (bei 4MHz Takt)
> auf das Ende des SPI zu pollen.
Momentan hab ich einen Takt von ca. 500kHz. Mehr ist eigentlich nicht 
nötig. Aber ich könnte den Takt auch auf 5MHz setzen und Pollen. Müsste 
ich jedoch zuerst testen.

> Nur byteweise wäre der Super-Gau.
Immer 512 Bytes in einem Rutsch (mit wenigen Ausnahmen).

> Täusche Dich nicht, hast Du mal konkrete Zahlen (µs je Zeichen). Große
> Zeichen dauern auch deutlich länger (mehr Pixel) als 5*7.
Zwischen meinem Controler und dem Dispay sitzt ein weiterer Controller 
(ist eine alte Bastelei). Hab das damals gemacht, um das Display per SPI 
ansteuern zu können, da das Display eine parallele Ansteuerung hat und 
ich zu wenig Pins hatte. Nun wird es in diesem Projekt weiterverwendet.
Ich muss lediglich über SPI die enzelnen Zeichen rausfeuern, den Rest 
erledigt der Controller am Display. Eigentlich könnte ich auch noch 
gleich die Grafik-Lib komplett auf diesen Controller auslagern und ihm 
dann nur die Befehle senden (z.B. zeichne Linie von Punkt X zu Y). 
Momentan muss ich für Grafiken eine Bitmap via SPI senden.

> Man sollte daher nicht zu häufig auf das LCD schreiben, alle 200ms ist
> ein ergonomischer Wert.
Seit die Stringumwandlung so schnell geht, starte ich den Task alle 
100ms. Jedes mal wenn durch Benutzereingaben die Ansicht wechselt, wird 
das Display sofort aktualisiert. Will doch nicht so lange auf mein Gerät 
warten :)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.