[Git][NTPsec/ntpsec][master] ntpviz: stop splitting/joining, keep lines as lists.
Gary E. Miller
gitlab at mg.gitlab.com
Wed Oct 19 17:56:36 UTC 2016
Gary E. Miller pushed to branch master at NTPsec / ntpsec
Commits:
2a736806 by Gary E. Miller at 2016-10-19T10:56:10-07:00
ntpviz: stop splitting/joining, keep lines as lists.
Sadly, while the code looks cleaner, is is not faster. Proof
that Python is relatively better at join/split than lists.
- - - - -
2 changed files:
- ntpstats/ntpviz
- pylib/statfiles.py
Changes:
=====================================
ntpstats/ntpviz
=====================================
--- a/ntpstats/ntpviz
+++ b/ntpstats/ntpviz
@@ -310,22 +310,20 @@ set rmargin 12
sys.stderr.write("ntpviz: WARNING: no loopstats to graph\n")
return ''
- # speedup by only sending gnuplot the data it will actually use
+ # speed up by only sending gnuplot the data it will actually use
plot_data = ''
for row in self.loopstats:
- rs = row.split()
# Python slice is too dumb to do this the easy way
# fields: time, time offset, and freq offset
- rc = rs[0] + ' ' + rs[1] + ' ' + rs[2] + '\n'
- plot_data += rc
+ plot_data += row[0] + ' ' + row[1] + ' ' + row[2] + '\n'
plot_data += "\ne\n"
# compute clock offset
- values = [float(line.split()[1]) for line in self.loopstats]
+ values = [float(line[1]) for line in self.loopstats]
stats = VizStats( values, "Local Clock Time Offset")
# compute frequency offset
- values_f = [float(line.split()[2]) for line in self.loopstats]
+ values_f = [float(line[2]) for line in self.loopstats]
stats_f = VizStats(values_f, "Local Clock Frequency Offset", freq=1)
out = stats.percs
@@ -381,9 +379,14 @@ file.</p>
stats = []
temps_data = ()
- plot_data = ""
+ plot_data = ''
for key in tempslist:
- plot_data += "\n".join(tempsmap[key]) + "\ne\n"
+ # speed up by only sending gnuplot the data it will actually use
+ for row in tempsmap[key]:
+ # Python slice is too dumb to do this the easy way
+ # fields: time, temp
+ plot_data += row[0] + ' ' + row[2] + '\n'
+ plot_data += "\ne\n"
plot_template = NTPViz.Common + """\
set title "%(sitename)s: Local Temparatures"
@@ -393,7 +396,7 @@ plot \\
""" % locals()
for key in tempslist:
- plot_template += "'-' using 1:3 title '%(key)s' with line, \\\n" \
+ plot_template += "'-' using 1:2 title '%(key)s' with line, \\\n" \
% locals()
# strip the trailing ", \n"
@@ -427,10 +430,11 @@ component of frequency drift.</p>
gps_data = ()
plot_data = ""
for key in gpslist:
- d = "\n".join(gpsmap[key])
- plot_data += d + "\ne\n" + d + "\ne\n"
- # remove trailing "e\n"
- plot_data = plot_data[:-2]
+ for row in gpsmap[key]:
+ # Python slice is too dumb to do this the easy way
+ # fields: time, tdop, nSats
+ plot_data += row[0] + ' ' + row[2] + ' ' + row[3] + '\n'
+ plot_data += "\ne\n"
plot_template = NTPViz.Common + """\
set title "%(sitename)s: Local GPS
@@ -443,8 +447,8 @@ plot \\
for key in gpslist:
plot_template += """\
-'-' using 1:3 title '%(key)s tdop' with line ls 1, \\
-'-' using 1:4 title '%(key)s nSat' with line ls 2 axis x1y2, \\
+'-' using 1:2 title '%(key)s tdop' with line ls 1, \\
+'-' using 1:3 title '%(key)s nSat' with line ls 2 axis x1y2, \\
""" % locals()
# strip the trailing ", \\n"
@@ -457,7 +461,7 @@ gpsd log file is created by the gps-log.py program.</p>
"""
ret = {'html' : exp, 'stats' : stats }
ret['title'] = "Local GPS"
- ret['plot'] = plot_template + plot_data
+ ret['plot'] = plot_template + plot_data + plot_data
return ret
def local_error_gnuplot(self):
@@ -515,18 +519,16 @@ line at 0ppm. Expected values of 99%-1% percentiles: 0.4ppm</p>
sys.stderr.write("ntpviz: WARNING: no loopstats to graph\n")
return ''
- # speedup by only sending gnuplot the data it will actually use
+ # speed up by only sending gnuplot the data it will actually use
plot_data = ''
for row in self.loopstats:
- rs = row.split()
# Python slice is too dumb to do this the easy way
# fields: time, fld, and rtt
- rc = rs[0] + ' ' + rs[fld - 1] + '\n'
- plot_data += rc
+ plot_data += row[0] + ' ' + row[fld - 1] + '\n'
plot_data += "\ne\n"
# grab and process the values
- values = [float(line.split()[fld - 1]) for line in self.loopstats]
+ values = [float(line[fld - 1]) for line in self.loopstats]
stats = VizStats( values, title, freq=freq )
# build the output dictionary, because Python can not format
@@ -601,6 +603,7 @@ plot \
peer_data = ()
plot_data = ""
namelist = [] # peer names
+
for key in peerlist:
# Trickiness - we allow peerlist elements to be DNS names.
# The socket.gethostbyname() call maps DNS names to IP addresses,
@@ -616,14 +619,12 @@ plot \
namelist.append(socket.getfqdn(key))
if ip in peerdict:
- # 20% speedup by only sending gnuplot the data it will
+ # 20% speed up by only sending gnuplot the data it will
# actually use
for row in peerdict[ip]:
- rs = row.split()
# Python slice is too dumb to do this the easy way
# fields: time, fld, and rtt
- rc = rs[0] + ' ' + rs[fld - 1] + ' ' + rs[4] + '\n'
- plot_data += rc
+ plot_data += row[0] + ' ' + row[fld - 1] + ' ' + row[4] + '\n'
plot_data += "\ne\n"
else:
sys.stderr.write("ntpviz: ERROR: No such peer as %s" % key)
@@ -649,8 +650,7 @@ useful to see how the measured offset is behaving.</p>
at 0s. Typical 90%% ranges may be: local serial GPS 200 ms; local PPS
20µs</p>
-<p>Clock Offset is field 5 in the peerstats log file. The Round Trip
-Time (rtt) is field 6 in the peerstats file.</p>
+<p>Clock Offset is field 5 in the peerstats log file.</p>
"""
else:
title = "Peer Offset " + str(peerlist[0])
@@ -668,7 +668,8 @@ rtt changes.</p>
at 0s. Typical 90% ranges may be: local LAN peer 80µs; 90% ranges for
WAN servers may be 4ms and much larger. </p>
-<p>Clock Offset is field 5 in the peerstats log file.</p>
+<p>Clock Offset is field 5 in the peerstats log file. The Round Trip
+Time (rtt) is field 6 in the peerstats file.</p>
"""
else:
@@ -698,7 +699,7 @@ at 0s.</p>
"""
# grab and sort the values, no need for the timestamp, etc.
- values = [float(line.split()[fld - 1]) for line in peerdict[ip]]
+ values = [float(line[fld - 1]) for line in peerdict[ip]]
stats = VizStats( values, title)
@@ -718,7 +719,7 @@ at 0s.</p>
# many peers
title += "s"
# grab and sort the values, no need for the timestamp, etc.
- values = [float(line.split()[fld - 1]) for line in self.peerstats]
+ values = [float(line[fld - 1]) for line in self.peerstats]
stats = VizStats( values, title )
@@ -800,7 +801,7 @@ plot \
# TODO normalize to 0 to 100?
# grab and sort the values, no need for the timestamp, etc.
- values = [float(line.split()[1]) for line in self.loopstats]
+ values = [float(line[1]) for line in self.loopstats]
stats = VizStats( values, 'Local Clock Offset' )
out = stats.percs
out['sitename'] = self.sitename
@@ -904,8 +905,14 @@ plot \\
for (i, stats) in enumerate(statlist):
plot += '"-" using 1:($2*1000000) title "%s clock offset μs" with linespoints, \\\n' % (sitenames[i])
plot = plot[:-4] + "\n"
+
for stats in statlist:
- plot += stats.dump("loopstats") + "e\n"
+ # speed up by only sending gnuplot the data it will actually use
+ for row in stats.loopstats:
+ # Python slice is too dumb to do this the easy way
+ # fields: time, temp
+ plot += row[0] + ' ' + row[1] + '\n'
+ plot += "\ne\n"
ret = {'html' : '', 'stats' : [] }
ret['title'] = "Multiplot"
@@ -1439,6 +1446,8 @@ ntpviz</a>, part of the <a href="https://www.ntpsec.org/">NTPsec project</a>
for (imagename, image) in imagepairs:
if not image:
continue
+ if 1 <= args.debug_level:
+ sys.stderr.write("ntpviz: plotting %s\n" % image['title'])
stats.append( image['stats'] )
# give each H2 an unique ID.
id = image['title'].lower()
=====================================
pylib/statfiles.py
=====================================
--- a/pylib/statfiles.py
+++ b/pylib/statfiles.py
@@ -25,17 +25,20 @@ class NTPStats:
"convert timestamp (MJD & seconds past midnight) to Unix time"
"Replace MJD+second with Unix time."
try:
- split = line.split(None, 2)
+ split = line.split()
mjd = int(split[0])
second = float(split[1])
except:
- # unparseable time 0 and it will be stripped later
+ # unparseable, skip this line
return None
# warning: 32 bit overflows
time = NTPStats.SecondsInDay * mjd + second - 3506716800
- if time < starttime or time > endtime:
- return None
- return str(time) + " " + split[2]
+ if starttime <= time <= endtime:
+ del split[0]
+ split[0] = str(time)
+ return split
+ # else
+ return None
@staticmethod
def timestamp(line):
@@ -95,7 +98,7 @@ class NTPStats:
if line is not None:
if 0 == len(line):
continue
- split = line.split(None, 2)
+ split = line.split()
try:
t = int(float(split[0]))
except:
@@ -103,7 +106,7 @@ class NTPStats:
continue
if starttime <= t <= endtime:
- lines1.append( line)
+ lines1.append( split)
else:
# Morph first field into Unix time with fractional seconds
for line in lines:
@@ -113,7 +116,7 @@ class NTPStats:
lines1.append( line)
# Sort by datestamp
- lines1.sort(key=lambda line: line.split()[0])
+ lines1.sort(key=lambda line: line[0])
setattr(self, stem, lines1)
def clip(self, start, end):
@@ -165,7 +168,7 @@ class NTPStats:
return self.peermap
for line in self.peerstats:
- ip = line.split()[1]
+ ip = line[1]
if ip not in self.peermap:
self.peermap[ip] = []
self.peermap[ip].append(line)
@@ -175,7 +178,7 @@ class NTPStats:
"Return a dictionary mapping gps sources to entry subsets."
gpsmap = {}
for line in self.gpsd:
- source = line.split()[1]
+ source = line[1]
if source not in gpsmap:
gpsmap[source] = []
gpsmap[source].append(line)
@@ -185,7 +188,7 @@ class NTPStats:
"Return a dictionary mapping temperature sources to entry subsets."
tempsmap = {}
for line in self.temps:
- source = line.split()[1]
+ source = line[1]
if source not in tempsmap:
tempsmap[source] = []
tempsmap[source].append(line)
View it on GitLab: https://gitlab.com/NTPsec/ntpsec/commit/2a73680669103b058c11fc695107a718bf643ad0
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ntpsec.org/pipermail/vc/attachments/20161019/51f38bf9/attachment.html>
More information about the vc
mailing list