• Stars
    star
    108
  • Rank 319,769 (Top 7 %)
  • Language
    Rust
  • License
    MIT License
  • Created about 7 years ago
  • Updated 8 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A high-performance, cross-platform file reverse utility

tac

tac is a high-performance, simd-accelerated, cross-platform rewrite of the GNU tac utility from Coreutils, released under a BSD-compatible (MIT) license. tac reads input from a file (or from stdin, but see below) and then prints it line-by-line backwards.

This tac implementation uses simd-acceleration for new line detection (read more about that here) and utilizes memory-mapped files on all supported operating systems. It is additionally written in rust for maximum integrity and safety.

Who needs a faster tac anyway?

Good question. Try grepping through a multi-gigabyte web access log file in reverse chronological order (tac --line-buffered access.log | grep foo) and then get back to me.

Usage

Usage: tac [OPTIONS] [FILE1..]
Write each FILE to standard output, last line first.
Reads from stdin if FILE is - or not specified.

Options:
  -h --help        Print this help text and exit
  -v --version     Print version and exit.
  --line-buffered  Always flush output after each line.

tac reads lines from any combination of stdin and/or zero or more files and writes the lines to the output in reverse order.

Example

$ echo -e "hello\nworld" | tac
world
hello

Installation

tac may be installed via cargo, the rust package manager:

cargo install tac

Help is humbly requested in getting tac into the package managers for various platforms. It's really a time-consuming task, especially for someone that only interacts with the various packaging tools once in a blue moon as opposed to on a daily basis.

Currently arm64 (aarch64) NEON acceleration is only available with the nightly compiler. If using it, provide the --features nightly flag to cargo to enable support.

Implementation Notes

This implementation of tac uses SIMD instruction sets (AVX2, NEON) to accelerate the detection of new lines. The usage of memory-mapped files additionally boosts performance by avoiding slowdowns caused by context switches when reading from the input if speculative execution mitigations are enabled. It is significantly (2.55x if mitigations disabled, more otherwise) faster than the version of tac that ships with GNU Coreutils, in addition to being more liberally licensed.

To obtain maximum performance:

  • Try not to pipe input into tac. e.g. instead of running cat /usr/share/dict/words | tac, run tac /usr/share/dict/words directly. Because tac by definition must reach the end-of-file before it can emit its input with the lines reversed, if you use tac's stdin interface (e.g. cat foo | tac), it must buffer all stdin input before it can begin to process the results. tac will try to buffer in memory, but once it exceeds a certain high-water mark (currently 4 MiB), it switches to disk-based buffering (because it can't know how large the input is or if it will end up exceeding the available free memory).
  • Always try to place tac at the start of a pipeline where possible. Even if you can guarantee that the input to tac will not exceed the in-memory buffering limit (see above), tac is almost certainly faster than any other command in your pipeline, and if you are going to reverse the output, you will benefit most if you reverse it from the start, unless you are always going to run the command to completion. For example, instead of running grep foo /var/log/nginx/access.log | tac, run tac /var/log/nginx/access.log | grep foo. This will (significantly) reduce the amount of time/work before the first n matches are reported (because the file is first quickly reversed then searched in the desired order, vs slowly searched in its entirety and only then are the results reversed).
  • Use line-buffered output mode (tac --line-buffered) if tac is piping into another command rather than writing to the tty directly. This gives you "live" streaming of results and lets you terminate much sooner if you're only looking for the first n matches. e.g. tac --line-buffered access.log | grep foo will print its first match much, much sooner than tac access.log | grep foo would.
  • In the same vein, if you are chaining the output of n utilities, make sure that all commands up to n - 1 are all using line-buffered mode unless you don't care about latency and only care about throughput. For example, to print the first two matches for some grep pattern: tac --line-buffered access.log | grep --line-buffered foo | head -n2.

License and Copyright

tac is released under the terms of the MIT public license. Copyright Mahmoud Al-Qudsi 2017-2021. All rights not assigned by the MIT license are reserved.

As an open source project, tac would not exist without the tireless efforts of its various contributors - see CONTRIBUTORS.md for full details.

More Repositories

1

pevents

Implementation of Win32 events for *nix platforms, built on top of pthreads.
C++
265
star
2

AsyncLock

An async/await-friendly lock for .NET, complete with asynchronous waits, safe reëntrance, and more.
C#
185
star
3

CppSQLite

A simple and easy-to-use cross-platform C++ wrapper for the SQLite API. Fork of the CppSQLite project, originally by Rob Groves, currently updated and maintained by NeoSmart Technologies.
C++
127
star
4

securestore-rs

A simple, encrypted, git-friendly, file-backed secrets manager for rust
Rust
126
star
5

SecureStore

A .NET implementation of the cross-platform SecureStore (symmetrically-encrypted secrets) protocol
C#
93
star
6

RunInBash

Run Linux commands under WSL without leaving your PowerShell or CMD!
C++
92
star
7

unicode.net

A Unicode library for .NET, supporting UTF8, UTF16, and UTF32. With an extra helping of emoji for good measure πŸ”₯🌢️😁
C#
87
star
8

msvcrt.lib

msvcrt.lib for linking against msvcrt.dll on all versions of Windows
C
82
star
9

SqliteCache

An ASP.NET Core IDistributedCache provider backed by SQLite
C#
80
star
10

prettysize-rs

Pretty-print file sizes and more
Rust
42
star
11

ln-win

JunctionPoint library and ln clone for Windows.
C++
33
star
12

udpproxy

Cross-platform UDP proxy
Rust
31
star
13

PrettySize.net

Format/print file sizes in a human-readable format.
C#
30
star
14

UrlBase64

A standards-compliant implementation of web/url-safe base64 encoding and decoding for .NET targets
C#
30
star
15

paste

A Windows utility that simply dumps the clipboard data to stdout
C++
26
star
16

rewrite

An in-place file rewrite utility, useful for redirecting output to same file as source.
Rust
26
star
17

betterpad

A better notepad. Still simple. Still fast.
C#
24
star
18

rsproxy

A simple, command-line TCP/UDP proxy server
Rust
23
star
19

cryptostream

Read and Write stream adapters for on-the-fly encryption and decryption for rust
Rust
21
star
20

rsevents

Auto- and manual-reset events for rust
Rust
19
star
21

uuidxx

Cross-platform C++ library for parsing and generating UUIDs or GUIDs. Windows, Mac, Linux, and BSD.
C++
19
star
22

LastPassTo1Password

A LastPass to 1Password converter.
C#
16
star
23

rsevents-extra

Extra event types built on top of rsevents
Rust
16
star
24

gmake-proxy

A BSD make (bmake) proxy that invokes GNU make (gmake) instead
Makefile
15
star
25

EasyBCD-Localization

EasyBCD localization files for NLT. Help us translate EasyBCD into your language, it's easy and rewarding!
Shell
14
star
26

StreamCompare

A .NET library and nuget package for stream comparison.
C#
12
star
27

UrlPreview

A .NET library for loading URL previews.
C#
11
star
28

collections

A collection of various data structures and containers for .NET Standard
C#
11
star
29

zipcat

Pipe contents of zip file to stdout, supporting multiple files.
Rust
11
star
30

open

Like macOS `open` but for Windows
C++
11
star
31

web

A collection of helpful classes and functions for writing ASP.NET projects, for both MVC and forms. Save time and effort with this small and highly-performant "framework."
C#
10
star
32

Localization

The NeoSmart Localization and Regionalization Toolkit (NLRT).
C#
9
star
33

TaskThreads

A Task-based System.Threading.Threads implementation for Universal Windows Platform applications.
C#
9
star
34

CargoMake

A Makefile for Cargo-based rust projects
Makefile
8
star
35

UtfRedirect

Helper application used to host a guest exe, transparently proxying bi-directional stdin and stdout traffic, forcing the console input and output codepages to UTF8/6501 in order to support internationalized stdin/stdout on Windows.
Rust
8
star
36

pkg-graph

A graphviz generator for pkg, the FreeBSD package manager
Rust
8
star
37

ExtensionMethods

A collection of helpful .NET extension methods for desktop and web development
C#
6
star
38

paypalnvp-dotnet

Minimal and lightweight PayPal NVP library for C# and .NET
C#
5
star
39

paypalnvp-php

Minimal and lightweight PayPal NVP Library for PHP.
PHP
4
star
40

run

A simple, invisible application launcher for Windows
C++
4
star
41

xf86-video-scfb

FreeBSD syscons framebuffer Xorg driver
Shell
4
star
42

nettest

Tiny and bare-bones command-line utility to test for the presence of an internet connection on Windows.
Rust
4
star
43

ignore-result

Adds `.ignore()` to rust `Result` types
Rust
4
star
44

RedisDictionary

A redis-backed persistent dictionary for C#, .NET, and .NET Core
C#
3
star
45

UwpTaskbarIcon

Taskbar icon library for Windows 10
C#
3
star
46

linqplus

Additional LINQ methods optimized for specific data structures, functional LINQ methods, and more.
C#
3
star
47

textlist

Generate properly formatted and grammatically correct text lists from arrays and IEnumerables.
C#
2
star
48

hashing.net

NeoSmart hashing library for .NET
C#
2
star
49

synchronization

A collection of async-friendly synchronization objects for .NET and .NET Core
C#
2
star
50

Stream.CopyTo

A Stream.CopyTo() implementation for .NET 2.0, 3.0, and 3.5
C#
2
star
51

bandit.net

A multi-armed bandit A/B testing library for .NET platforms
C#
2
star
52

nst-ses

Community fork of Amazon's AWS SES (Simple Email Service) Perl framework. Contains important compatibility and integration improvements.
Perl
2
star
53

ms-sys

C
2
star
54

nst-log

A basic and cross-platform logging library for C++ applications. Features an easy to use singleton class, a simple API, convience wrappers, and very little overhead. For those looking for a logging library that doesn't overwhelm.
C++
2
star
55

showkeys

Rust
1
star
56

wp-prism

A githubesque syntax highlighting and code fencing plugin for WordPress.
PHP
1
star
57

relaunch

A simple, cross-platform, zero-configuration process monitor/relauncher
Rust
1
star
58

hivexx

C++ wrapper around the excellent hivex library, focused on safety and speed.
C++
1
star
59

UwpCache

An object cache for UWP applications.
C#
1
star