# Geschwindigkeit und Genauigkeit bei Zeitmessung



## poschdi (15. Jun 2005)

Ich hab mal eine allgemeine Javafrage zur Geschwindigkeit. Dazu erst mal eine kurze Situationsbeschreibung. Ich hatte vor einiger Zeit angefangen, für den Rennsport eine Zeitmessanlage mittels Infrarot zu entwickeln. Ein Fahrzeug bekommt dabei einen Sender, der ein codiertes Lichtsignal sendet. Wird dies von einem Empfänger am Streckenrand erkannt, so wird dieser Code an eine Software weitergereicht. Aktuell ist diese in VB6 geschrieben. Die Software berechnet dann die Rundenzeit und fertigt verschiedene Statistiken an. Da VB aber keine Threads unterstützt, kann es hier schon mal zu Unterbrechungen führen. Z.B. Wenn man etwas Drucken möchte wird immer direkt das ganze Programm blockiert. Prinzipell wäre es zwar auch möglich die Zeit direkt im Empfänger zu messen, dies hätte aber auch Nachteile, z.B. wenn man mit mehreren Empfängern auch Zwischenzeiten berechnen möchte.

Nun steht die Frage im Raum, wie man das verbessern kann. Da ich ein bisschen Ahnung von Java noch aus dem Studium habe und diese gerne wieder etwas auffrischen möchte, würde ich Java bevorzugen. Nun weiss ich aber nicht, ob ich hiermit dort ähnliche Probleme bekomme. Es sollte also ein Thread im Hintergrund laufen, der ständig die serielle Schnittstelle abhört und sobald etwas empfangen wird die vergangene Zeit berechnet. Bekommt man das mit Java einigermaßen genau hin?

gruß poschdi


----------



## Bleiglanz (15. Jun 2005)

die Frage ist WIE GENAU?

schon bei einer stinknormalen System.currentTimeMillis hat man eine ungenauigkeit von 20-50 ms, hängt vom OS ab

wenn du noch die serielle Schnittstelle und den IO zeugs und die Tatsache, dass Threads dabei sind berücksichtigst, würde ich 500ms MINIMUM Ungenauigkeit einplanen


----------



## poschdi (15. Jun 2005)

Wenn man bei der Übertragungzeit vom Empfänger zum PC davon ausgeht, dass diese immer ähnlich ist, muss man diese Zeit nicht so genau nehmen. Also, wenn es jedes mal zwischen Empfänger und Software 500ms dauert, so wird die Rundenzeit dadurch ja nicht beeinflusst. Kristischer wäre es, wenn es mal 100ms und mal 500ms wären. Daher würde es mich interessieren, wieviel Zeitschwankung Java hier ausmachen kann, bzw. ob und wieviel andere Sprachen hier besser sind. 20 bis 50ms wären wohl vertretbar. Die offizellen Zeitnahmen via Transponderschleife sind übrigens auch ned 100% genau, und für die F1 ist auch ned gedacht 

Mit dem aktuellen VB6 Programm, komme ich einigermaßen genau an die offizelle Zeit ran. Wobei ich nicht weiss, wer hier wieweit von der wirklichen Zeit entfernt ist


----------



## stev.glasow (15. Jun 2005)

poschdi hat gesagt.:
			
		

> Kristischer wäre es, wenn es mal 100ms und mal 500ms wären.


Das meinte Bleiglanz, obwohl ich nicht verstehe wieso das so hoch sein sollen.

[edit]
Wie sieht es eigentlich mit der Genauigkeit von System#nanoTime() aus? Wenn die ähnlich ungau wie System#currentTimeMillis() ist verstehe ich den Sinn dieser Funktion nicht.


----------



## poschdi (15. Jun 2005)

Hmm aber die Dauer wie lange ein Zeichen von A nach B braucht, sollte doch bei einer seriellen Verbindung gleichbleiben. So könnte ja nur die Zeit schwanken wie lang es dauert, bis das Zeichen aus dem Puffer gelesen wird. Dort würde ich auch ned verstehen, warum dies sich in einem so großen Rahmen abspielen soll.


----------



## Bleiglanz (15. Jun 2005)

nanoTime ist wohl nur ein Gag

wenn mehrere Threads laufen hat man eben bei java überhaupt keine Kontrolle darüber, wann einer wieder aufwacht und an der reihe ist

rundenmessung liegt an der seriellen schnittstelle

ABER der lese-thread schläft gerade

d.h. es gibt eine Verzögerung, bis der das nächste mal aufwacht

und da würde ich doch grössere Schwankungen vermuten...


----------



## stev.glasow (15. Jun 2005)

Und wenn man einen Thread macht der nur fürs aufnehmen der Daten zuständig ist, (sprich der auf der Schnittstelle liest) und dessen Priorität höher setzt als die der anderen?
Dann sollte er doch eigentlich sofort "aufwachen" oder zumindest sollten dann die Verzögerungen geringer sein, oder?


----------



## Wildcard (15. Jun 2005)

stevg hat gesagt.:
			
		

> [edit]
> Wie sieht es eigentlich mit der Genauigkeit von System#nanoTime() aus? Wenn die ähnlich ungau wie System#currentTimeMillis() ist verstehe ich den Sinn dieser Funktion nicht.


Hab mich auch schon gefragt wie genau nanoTime wirklich ist.
Das einzige was ich bei SUN dazu finde ist:


			
				SUN hat gesagt.:
			
		

> The actual precision of System.nanoTime is platform-dependent.


  :bae: 
Nach dem was ich bisher gelesen habe funktioniert die Zeitmessung aber nach einem anderen Prinzip als currentTimeMillis und soll (zumindest) differenzierter sein.
Zum Vergleich die kleinste Änderung die System.currentTimeMillis anzeigen kann:
Windows 95/98 :  55ms
2000/NT/XP : 10-15ms
insofern kanns ja nur besser werden.

hier mal mein eigener 'Pseudo-Benchmark'  :wink: 

```
public class TimeBenchmark
{

	/**
	 * @param args
	 */
	public static void main(String[] args)
	{
		// TODO Auto-generated method stub
		for(int i=0;i<1000000;i++)
		{
			
		}
		long time1 = -System.nanoTime();
		time1 += System.nanoTime();
		long time2 = -System.nanoTime();
		time2 += System.nanoTime();
		long time3 = -System.nanoTime();
		time3 += System.nanoTime();
		long time4 = -System.nanoTime();
		time4 += System.nanoTime();

		long time5 = -System.currentTimeMillis();
		time5 += System.currentTimeMillis();
		long time6 = -System.currentTimeMillis();
		time6 += System.currentTimeMillis();
		long time7 = -System.currentTimeMillis();
		time7 += System.currentTimeMillis();
		long time8 = -System.currentTimeMillis();
		time8 += System.currentTimeMillis();
		
		System.out.println("Nano:");
		System.out.println(time1);
		System.out.println(time2);
		System.out.println(time3);
		System.out.println(time4);
		System.out.println("Milli:");
		System.out.println(time5);
		System.out.println(time6);
		System.out.println(time7);
		System.out.println(time8);
		
	}

}
```

Das kommt raus:
Nano:
12850
8102
7264
7264
Milli:
0
0
0
0

zumindest sieht man das es nicht 
System.currentTimeMillis() * 1000 ist  :wink:


----------



## Bleiglanz (15. Jun 2005)

AFAIK ist das mit den Prioritäten auch so eine Sache

selbst bei der höchsten Priorität dürfen ja die anderen nicht verhungern....

aber man könnte wahrscheinlich (durch geschicktes Design) schon irgendwie mit der Sache klarkommen

etwa einen ganz eigenen Betriebssystem Prozess (von mir aus auch in Java gemacht) der NUR auf eingehende Daten von der seriellen Schnittstelle horcht und diese sofort in eine Datenbank schaufelt...


----------



## messi (15. Jun 2005)

Wildcard hat gesagt.:
			
		

> zumindest sieht man das es nicht
> System.currentTimeMillis() * 1000 ist  :wink:


Wäre auch dumm, weil es ja Nano- und nicht Mikrosekunden sind  :bae:


----------



## Wildcard (15. Jun 2005)

messi hat gesagt.:
			
		

> Wildcard hat gesagt.:
> 
> 
> 
> ...


Nanosekunden-Genauigkeit kriegst du damit aber auch nicht hin.


----------



## poschdi (16. Jun 2005)

Also am besten, ich schreib nen kleinen Prototypen, den ich dann durchteste.


----------



## stev.glasow (16. Jun 2005)

Kannst ja dann mal berichten wie du das gelöst hast und wie gross die Abweichungen sind.


----------



## poschdi (16. Jun 2005)

Joah kann ich machen. Kann nur einige Zeit dauern, da ich aktuell noch ein anderes Projekt am laufen hab


----------

