Von dem Code, den ich geschrieben habe, befinden sich die meisten guten Dinge in CCAN , während der Rest in bestehenden Open-Source-Projekten tendenziell bessere Versionen findet. Heutzutage schreibe ich immer weniger Universal-Misc-Code, um anwendungsspezifische Varianten dieses Codes zu schreiben, oder um Universal-Module zu schreiben, die ich selbst freigeben kann.
C
Hier ist eine Funktion und typedef, die ich mehr als einmal verwendet habe. Für Anwendungen, die ein Timing benötigen, ist es in Bezug auf die Einfachheit schwer, Millisekunden zu übertreffen:
#include <stdint.h>
#include <sys/time.h>
typedef int64_t msec_t;
static msec_t time_ms(void)
{
struct timeval tv;
gettimeofday(&tv, NULL);
return (msec_t)tv.tv_sec * 1000 + tv.tv_usec / 1000;
}
Und noch mehr verschiedene C-Funktionen, die ich immer und immer wieder (und immer wieder) benutze:
/* Remove a trailing newline, if present. */
void chomp(char *buffer)
{
if (!*buffer)
return;
while (*buffer)
buffer++;
if (buffer[-1] == '\n')
buffer[-1] = 0;
}
/*
* Skip whitespace, update the pointer, and return it.
* Example:
*
* switch (*skipSpace(&s)) {
* case '\0':
* ...
* case '(':
* ...
*/
const char *skipSpace(const char **sptr)
{
const char *s = *sptr;
while (isspace(*s))
s++;
*sptr = s;
return s;
}
/* Scramble an array of items uniformly. */
void scramble(void *base, size_t nmemb, size_t size)
{
char *i = base;
char *o;
size_t sd;
for (;nmemb>1;nmemb--) {
o = i + size*(rand()%nmemb);
for (sd=size;sd--;) {
char tmp = *o;
*o++ = *i;
*i++ = tmp;
}
}
}
Haskell
Haskells nub :: (Eq a) => [a] -> [a]
Funktion ist O (n²), weil anhand der Typensignatur nur geprüft werden darf, ob zwei Elemente gleich sind. Eine einfache O (n log n) -Alternative ist map head . group . sort
, dass jedoch die gesamte Eingabeliste vor der Ausgabe erzwungen werden muss, während nub
die Ausgabe sofort beginnen kann. Das Folgende ist eine Alternative zu O (n log n) nub
, die bereits gesehene Elemente in einem sammelt Data.Set
:
module Nub (nub') where
import Prelude
import Data.Set (empty, member, insert)
nub' :: Ord a => [a] -> [a]
nub' xs = loop xs empty where
loop [] _ = []
loop (x:xs) set =
if x `member` set
then loop xs set
else x : loop xs (insert x set)
In Haskell, verwende ich Alternativen zu sequence
, mapM
, forM
, replicateM
, und filterM
. Diese Aktionen generieren jeweils eine Liste, aber die Liste kann erst verwendet werden, wenn die Aktion vollständig abgeschlossen ist (wenn Sie eine strenge Monade wie IO verwenden). Die Alternativen bilden die Liste in umgekehrter Reihenfolge, anstatt einen Turm aus Thunks zu bilden, was ich durch Benchmarking zumindest mit GHC als schneller empfand.
sequence' :: Monad m => [m a] -> m [a]
sequence' ms = loop ms [] >>= return . reverse where
loop [] xs = return xs
loop (m:ms) xs = do
x <- m
loop ms (x:xs)
mapM' :: Monad m => (a -> m b) -> [a] -> m [b]
mapM' f xs = sequence' $ map f xs
forM' :: Monad m => [a] -> (a -> m b) -> m [b]
forM' = flip mapM'
replicateM' :: Monad m => Int -> m a -> m [a]
replicateM' n x = sequence' (replicate n x)
filterM' :: Monad m => (a -> m Bool) -> [a] -> m [a]
filterM' pred xs = loop xs [] >>= return . reverse where
loop [] xs' = return xs'
loop (x:xs) xs' = do
keep <- pred x
loop xs (if keep then (x:xs') else xs')
Hinweis: sequence_
, mapM_
, forM_
, und replicateM_
Funktionen sind immer noch eine bessere Wahl , wenn Sie in der Ergebnisliste nicht interessiert sind.