Skip to content

Commit f20a55c

Browse files
committed
optimized
1 parent 9d26f45 commit f20a55c

File tree

1 file changed

+52
-22
lines changed

1 file changed

+52
-22
lines changed

Linux/tss/src/main.rs

Lines changed: 52 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ struct Config {
1717
delta: bool,
1818
prefix_only: bool,
1919
color: bool,
20-
unbuffered: bool,
20+
buffered: bool,
2121
timezone: Option<String>,
2222
}
2323

@@ -36,7 +36,7 @@ impl Config {
3636
delta: false,
3737
prefix_only: false,
3838
color: false,
39-
unbuffered: true,
39+
buffered: false, // Default to unbuffered for real-time output
4040
timezone: None,
4141
};
4242

@@ -63,7 +63,7 @@ impl Config {
6363
"--delta" => config.delta = true,
6464
"--prefix-only" => config.prefix_only = true,
6565
"--color" => config.color = true,
66-
"--buffered" => config.unbuffered = false,
66+
"--buffered" => config.buffered = true,
6767
"-s" | "--separator" => {
6868
i += 1;
6969
if i >= args.len() {
@@ -105,6 +105,10 @@ impl Config {
105105
eprintln!("Error: Cannot use both --relative and --epoch");
106106
std::process::exit(1);
107107
}
108+
if config.relative && config.delta {
109+
eprintln!("Error: Cannot use both --relative and --delta");
110+
std::process::exit(1);
111+
}
108112

109113
Ok(config)
110114
}
@@ -155,7 +159,9 @@ Examples:
155159
tail -f app.log | {} -r -m # Relative monotonic
156160
cat file.txt | {} --delta # Show time between lines
157161
ping host | {} --color --microseconds # Colored with microseconds
158-
command | {} --prefix-only # Only timestamps",
162+
command | {} --prefix-only # Only timestamps
163+
164+
Note: --relative and --delta are mutually exclusive",
159165
program_name, program_name, program_name, program_name, program_name,
160166
program_name, program_name, program_name, program_name, program_name, program_name
161167
);
@@ -228,6 +234,8 @@ struct TimeFormatter {
228234
custom_format: Option<String>,
229235
timestamp_buf: String,
230236
color: bool,
237+
color_prefix: &'static str,
238+
color_suffix: &'static str,
231239
}
232240

233241
impl TimeFormatter {
@@ -240,6 +248,12 @@ impl TimeFormatter {
240248
None
241249
};
242250

251+
let (color_prefix, color_suffix) = if config.color {
252+
("\x1b[36m", "\x1b[0m") // Cyan color
253+
} else {
254+
("", "")
255+
};
256+
243257
Self {
244258
format_type,
245259
utc: config.utc,
@@ -251,25 +265,32 @@ impl TimeFormatter {
251265
custom_format,
252266
timestamp_buf: String::with_capacity(128),
253267
color: config.color,
268+
color_prefix,
269+
color_suffix,
254270
}
255271
}
256272

257273
#[inline]
258274
fn format_timestamp(&mut self, monotonic: bool) -> &str {
259275
self.timestamp_buf.clear();
260276

261-
if self.color {
262-
self.timestamp_buf.push_str("\x1b[36m"); // Cyan color
263-
}
264-
265277
match &self.format_type {
266278
FormatType::Delta => {
267279
let duration = if monotonic {
268280
let instant = Instant::now();
269281
let duration = if let Some(last) = self.last_instant {
270282
instant.duration_since(last)
271283
} else {
272-
std::time::Duration::ZERO
284+
// Initialize with current time for first call
285+
self.last_instant = Some(instant);
286+
return if self.color {
287+
self.timestamp_buf.push_str(self.color_prefix);
288+
self.timestamp_buf.push_str("0.000000");
289+
self.timestamp_buf.push_str(self.color_suffix);
290+
&self.timestamp_buf
291+
} else {
292+
"0.000000"
293+
};
273294
};
274295
self.last_instant = Some(instant);
275296
duration
@@ -278,7 +299,16 @@ impl TimeFormatter {
278299
let duration = if let Some(last) = self.last_time {
279300
time.duration_since(last).unwrap_or_default()
280301
} else {
281-
std::time::Duration::ZERO
302+
// Initialize with current time for first call
303+
self.last_time = Some(time);
304+
return if self.color {
305+
self.timestamp_buf.push_str(self.color_prefix);
306+
self.timestamp_buf.push_str("0.000000");
307+
self.timestamp_buf.push_str(self.color_suffix);
308+
&self.timestamp_buf
309+
} else {
310+
"0.000000"
311+
};
282312
};
283313
self.last_time = Some(time);
284314
duration
@@ -414,13 +444,13 @@ impl TimeFormatter {
414444
if let Some(ref fmt) = self.custom_format {
415445
// For relative timestamps, create a time from the duration
416446
let total_secs = duration.as_secs();
417-
let subsec_millis = duration.subsec_millis();
447+
let subsec_nanos = duration.subsec_nanos();
418448
let hours = (total_secs / 3600) as u32;
419449
let mins = ((total_secs % 3600) / 60) as u32;
420450
let secs = (total_secs % 60) as u32;
421451

422452
let dt = Utc.with_ymd_and_hms(1970, 1, 1, hours, mins, secs).unwrap()
423-
.with_nanosecond(subsec_millis * 1_000_000).unwrap();
453+
.with_nanosecond(subsec_nanos).unwrap();
424454

425455
use std::fmt::Write;
426456
let _ = write!(self.timestamp_buf, "{}", dt.format(fmt));
@@ -448,8 +478,12 @@ impl TimeFormatter {
448478
},
449479
}
450480

481+
// Add color codes if needed - do this outside the timestamp buffer
482+
// to avoid reallocation on every call
451483
if self.color {
452-
self.timestamp_buf.push_str("\x1b[0m"); // Reset color
484+
// Create a temporary string with color codes
485+
let colored = format!("{}{}{}", self.color_prefix, self.timestamp_buf, self.color_suffix);
486+
self.timestamp_buf = colored;
453487
}
454488

455489
&self.timestamp_buf
@@ -463,14 +497,10 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
463497
let stdin = io::stdin();
464498
let stdout = io::stdout();
465499

466-
// Use larger buffers for better performance unless unbuffered
467-
let buffer_size = if config.unbuffered { 0 } else { 256 * 1024 };
500+
// Use appropriate buffer sizes based on configuration
501+
let buffer_size = if config.buffered { 256 * 1024 } else { 0 };
468502
let reader = BufReader::with_capacity(128 * 1024, stdin);
469-
let mut writer = if config.unbuffered {
470-
BufWriter::with_capacity(0, stdout)
471-
} else {
472-
BufWriter::with_capacity(buffer_size, stdout)
473-
};
503+
let mut writer = BufWriter::with_capacity(buffer_size, stdout);
474504

475505
let separator_bytes = config.separator.as_bytes();
476506
let newline = b"\n";
@@ -489,8 +519,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
489519

490520
writer.write_all(newline)?;
491521

492-
// Always flush when unbuffered (which is now default)
493-
if config.unbuffered {
522+
// Flush when unbuffered
523+
if !config.buffered {
494524
writer.flush()?;
495525
}
496526
}

0 commit comments

Comments
 (0)