Jump to content

Performance der Programmiersprachen (RasPi)


Recommended Posts

bei mir dauert ein method call über java ca. 1.5ms .. was ich gelesen habe wirds nie unter 1ms gehen, da es usb nicht zulässt.

 

was die programmiersprache am RPi angeht:

C wird natürlich schneller sein als java.. aber es hängt davon ab was du machen willst.. kann leicht sein dass java reicht

python wird soviel ich weiss nativ vom RPi unterstützt.. da hast du aber einen overhead, da python interpretiert wird

Link to comment
Share on other sites

naja es ist nur ein einziger method call und 1.5ms ist find ich 'viel' zeit.

 

weiß jemand wie hoch genau die latenzen bei usb sind? wenn das mit 1ms pro request stimmt, müssten es bei einem get-request ja mindestens 2ms (rtt) sein.. oder wird eine maximale latenz von 1ms garantiert und weniger kanns immer sein?

Link to comment
Share on other sites

@kuli: USB wird 1x pro ms gepollt vom Linux Kernel (oder auch von Windows, ist so im Standard definiert). Die Antwort auf ein getter ist immer direkt beim nächsten polling vom PC fertig. D.h. so eine Anfrage dauert minimal 1ms und maximal 2ms, je nachdem wo du dich gerade in diesem Abfragefenster befindest.

 

Deswegen schreiben wir überall das unbedingt wenn möglich die Callbacks benutzt werden soll, da ist dann die absolut maximale Latenz nach auftreten eines Events 1ms, im Schnitt 500us.

Link to comment
Share on other sites

Java kann btw. locker genauso schnell wie C sein. Prinzipiell liegt es am Ende nur daran, dass der JIT guten Code erzeugt ^^

Man kann mir gerne erzählen, dass Java ein anderen Speicherverhalten hat als C (klar, weil C nicht managed ist), aber irgendwann sollte man mal damit aufräumen, dass C "automagisch" schneller ist weil es eben C ist.

Link to comment
Share on other sites

kurzer Ausflug:

Wenn du deinen C Code kompilierst, dann wird daraus durch den Compiler Maschinencode erzeugt, also Code der unmittelbar durch den Prozessor ausgeführt werden kann.

 

Wenn du deinen Java-Code kompilierst, dann wird daraus Byte-Code, dieser kann nicht von der CPU ausgeführt werden, bei Java gibt es den Just-In-Time-Compiler (JIT) der den Bytecode während der ausführung zu Maschinencode umwandelt, deswegen sind Java-Programme auch grundsätzlich Plattformunabhängig.

 

Wenn du C-Code kompiliert hast wirst du soetwas wie Optimierungen kennen. Dabei verändert der Compiler den Maschinencode so, dass er schneller ausgeführt werden kann, aber äquivalent zur Eingabe ist.

EInfaches Beispiel:

for(int i=0;i<3;i++)
  rufeMethode();

 

daraus kann der Compiler dann auch das machen (dargestellt als C-Code):

rufeMethode();
rufeMethode();
rufeMethode();

 

Der Prozessor muss gar keine Sprünge mehr ausführen (wie es bei der Schleife nötig wäre) und der Code ist schneller.

 

Der JIT kann das auch machen, aber es dauert halt länger solche Stellen zu finden. Für den C-Compiler ist es egal, der hat Zeit. Der JIT soll halt "in-time" arbeiten, deswegen wird er hin und wieder den Code nur "einfach kompilieren", dann wird dieser langsamer ausgeführt als äquivalenter (und optimierter!) C-Code.

 

Auf der anderen Seite kann der JIT bei Methoden die schnell sein müssen sich auch später nochmal "Mühe geben" und sie dann halt optimiert kompilieren.

 

Der JIT hat sogar einen Vorteil gegenüber dem C-Compiler: Er kennt die Laufzeitcharakteristik deines Programms, er kann wissen welche Methoden wie oft gerufen werden und dadurch besser optimieren.

 

Bei C# sieht das alles übrigens ähnlich aus, es gibt auch Zwischencode der live zu Maschinencode wird. Selbstverständlich war das alles jetzt ziemlich kurz dargestellt, aber das Fazit sollte ungefähr dieses sein: Java-Code ist nicht per se langsamer, er wird es an manchen Stellen aufgrund schlechter JIT-Entscheidungen sein, an anderen kann er aber auch schneller sein als der meiste C-Code. Letztendlich mact den größten Performance-Unterschied die Wahld er richtigen Algorithmen aus, nicht die Wahl der richtigen Programmiersprache.

Link to comment
Share on other sites

Ich will hier nciht den Glaubenskrieg im FOrum anzetteln, der wird im restlichen Internet genug geführt...

 

In C ist auch Speicherverwaltung nötig, die einen machen sie nicht und haben deswegen Mem-leaks, die anderen machen es und kommen bei großen Anwendungen auf die Idee "kluge Pointer" zu nutzen, das ist auch nur nen verkleideter GC.

 

Das mit dem Late Binding ist ein Punkt der auch C/C++ trifft. In C# beispielsweise ist es genau wie dort: Nur virtual/abstract kann überschrieben werden (während in java alles überschrieben werden kann was nciht final ist, also nur umgekehrte Logik).

Link to comment
Share on other sites

kurzer Ausflug:

Wenn du deinen C Code kompilierst, dann wird daraus durch den Compiler Maschinencode erzeugt, also Code der unmittelbar durch den Prozessor ausgeführt werden kann.

Also ich fand die Erklärung recht gelungen. Sehr gut, der Hinweis über "saubere"

Programmierung bzw. Verwendung von vernünftigen Design Patterns. Damit wird der Code nicht nur übersichtlicher, und wartbarer sondern auch u.U. performanter.

 

Keine Sorge, daß hier zuviel Infos rüberkommen. Im Forum wird m.E. eher viel zu wenig gepostet, als zu viel  ;)

 

Keine Ahnung wie das interne Verhalten beim Delphi oder FPC ist, aber die Compiler erzeugen ohne Umweg von Byte-Code direkt platform-abhängigen nativen Code. Ich schätze mal ähnlich des C-Compilers, aber mit dem Overhead der VCL, Kapselung der WinAPI etc.

 

PS: Habe die Zeit von der Fkt. GetChipTemperature kabelgeb. in Delphi gemessen, ich komme im Durchschn. auf 2ms auf einem i5,Win7 x64,8GB. Also die 1.5ms mit Java (abgesehen von JIT Optim.) entspricht kaum der Regel zur Laufzeit, ob es mit C dauerhaft erreicht möchte ich auch stark bezweifeln. Das Betriebssystem und seine zahlreichen bekannten und unbekannten Hintergrund-Prozesse/Threads dürften da Einfluß nehmen.

Link to comment
Share on other sites

du misst hier die gesamte ausführungszeit des programms. d.h. es muss geladen werden, dann wird irgendwann die ipconnection initialisiert, ... und dann erst wird die methode aufgerufen. von daher finde ich die zeiten nicht so merkwürdig. wenn du die zeit für den methodenaufruf selbst wissen willst, musst du das über die programmiersprache lösen. in java geht das mit

System.nanoTime()

Link to comment
Share on other sites

also am pc ist es erheblich schneller:

 

user@pc1:~/NetBeansProjects$ time java -jar temp/dist/temp.jar 
24.75

real	0m0.441s
user	0m0.120s
sys	0m0.020s

 

liegt das rein an der leistung vom system? also kann ich davon ausgehen dass am raspi keine schnellere abfrage möglich ist?

geht mir darum zu erfahren, ob das so korrekt ist, oder ob mein system nicht korrekt arbeitet...

Link to comment
Share on other sites

ja das lieg wahrscheinlich an der leistung des systems. aber wie gesagt, die meiste zeit geht beim laden und initialisieren verloren. wenn das programm mal läuft, gehen die einzelnen abfragen bestimmt schneller.

mach mal eine messung vom methodenaufruf selbst!

ist es notwendig dass du bei jeder abfrage das programm erneut starten musst?

Link to comment
Share on other sites

Hi,

ist es notwendig dass du bei jeder abfrage das programm erneut starten musst?

ich habe mir angewöhnt java nur als schnittstelle für die TF komponenten zu nutzen. die meiste logik packe ich dann in shellscripte, da diese doch erheblich einfacher sind und man "mal schnell" was ändern / ausprobieren kann.

 

bin z.b. grade dran, das relais-bricklet online-fähig zu machen:

root@raspi:/tmp# time java -jar /tmp/JARs/relais/relais.jar 3
[relay1 = true, relay2 = true]

 

mit dem aufruf von "relais.jar 3" gebe ich mir den status der relais aus. "relais.jar 1 1" schaltet beide relais ein, "relais.jar 2 0" lässt das erste relais unverändert, und schaltet das zweite aus.

also 0 = aus, 1 = ein, 2 = nichts ändern, 3 = status anzeigen.

 

nun kann ich über "exec" per php ein kleines shellscript starten, und mit dem relais den taster vom garagentorantrieb schalten. aufruf der url dann natürlich per smarthone, da der normale handsender erst funktioniert wenn man schon davor steht ;-)

Link to comment
Share on other sites

Ich würde auch empfehlen entweder direkt PHP-Bindings zu nutzen.

 

Ansonsten ist die unnötige Rechenarbeit riesig:

- Prozess erzeugen

- Programm vom Speicher (SD/HDD) laden

- TCP-Verbindung aufbauen

 

Die beiden letzten Punkte bedeuten jeweils unnötigen IO. IO ist immer langsam ^^

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...