mirror of
https://github.com/carp-lang/Carp.git
synced 2024-09-11 05:25:28 +03:00
multiple fixes:
- don’t do function copying in benchmarking - fix the array_update benchmark - add Filepath.file-from-path - add tests for the `Filepath` module - reformat a lot of documentation
This commit is contained in:
parent
e24fd38258
commit
9848e8fb34
@ -10,7 +10,7 @@
|
||||
|
||||
(defn some-updating []
|
||||
(let-do [a (replicate n &12345)
|
||||
b (aupdate a 0 inc-ref)]
|
||||
b (aupdate a 0 &inc-ref)]
|
||||
(assert (= (nth &b 0) &12346))
|
||||
(assert (= (nth &b 1) &12345))))
|
||||
|
||||
|
@ -8,7 +8,9 @@
|
||||
(private min-runs)
|
||||
(hidden min-runs)
|
||||
|
||||
(doc set-min-runs! "Set the minimum number of runs. If your functions takes a large amount of time, experimenting with this might make sense.")
|
||||
(doc set-min-runs! "sets the minimum number of runs to `n`.
|
||||
|
||||
If your functions takes a large amount of time, experimenting with this might make sense. The default value is `50`, which means that your function runs at least `50` times before even hitting a timeout.")
|
||||
(defn set-min-runs! [n]
|
||||
; / 2 because we run it twice per benchmarking run,
|
||||
; but this is an implementation detail
|
||||
@ -36,7 +38,7 @@
|
||||
(defn ns-iter-inner [f n]
|
||||
(let [start (get-time-elapsed)]
|
||||
(do
|
||||
(for [i 0 n] (ignore (f)))
|
||||
(for [i 0 n] (ignore (~f)))
|
||||
(Double.- (get-time-elapsed) start))))
|
||||
|
||||
(private print-bench-results)
|
||||
@ -55,7 +57,7 @@
|
||||
samples (Array.replicate min-runs &zero)]
|
||||
(do
|
||||
(for [i 0 min-runs]
|
||||
(Array.aset! &samples i (Double./ (ns-iter-inner @&f (Double.to-int n)) n))) ;; TODO: Get rid of '@&' here.
|
||||
(Array.aset! &samples i (Double./ (ns-iter-inner f (Double.to-int n)) n)))
|
||||
(Statistics.summary &(Statistics.winsorize &samples 5.0)))))
|
||||
|
||||
(private min-one)
|
||||
@ -65,9 +67,9 @@
|
||||
|
||||
; it is actually possible to make this run forever by supplying a _really_
|
||||
; long-running function, where long-running is everything over 30ms.
|
||||
(doc bench "Benchmark function f and print the results.")
|
||||
(doc bench "benchmarks the function `f` and prints the results to `stdout`.")
|
||||
(defn bench [f]
|
||||
(let [ns (ns-iter-inner @&f 1) ;; @& HACK, TODO: Should be able to pass the ref instead
|
||||
(let [ns (ns-iter-inner &f 1)
|
||||
ns-target-total 1000000.0
|
||||
_n (Double./ ns-target-total (min-one ns))
|
||||
n (min-one _n)
|
||||
@ -77,8 +79,8 @@
|
||||
(do
|
||||
(while (and (Double.< total 3000000000.0) (not done))
|
||||
(let [loop-start (get-time-elapsed)
|
||||
summ (get-samples @&f n) ;; @& HACK, TODO: Should be able to pass the ref instead
|
||||
summ5 (get-samples @&f n) ;; @& HACK, TODO: Should be able to pass the ref instead
|
||||
summ (get-samples &f n)
|
||||
summ5 (get-samples &f n)
|
||||
loop-run (- (get-time-elapsed) loop-start)]
|
||||
(if (and
|
||||
(Double.> loop-run 100000.0)
|
||||
|
@ -8,7 +8,7 @@
|
||||
(register from-int (Fn [Int] Char))
|
||||
(register copy (Fn [&Char] Char))
|
||||
|
||||
(doc meaning "Convert a numerical char into the appropriate number.")
|
||||
(doc meaning "converts a numerical char into the appropriate number (e.g. from `\1` to `1`).")
|
||||
(defn meaning [char-ref]
|
||||
(cond
|
||||
(= @char-ref \0) 0
|
||||
@ -26,11 +26,11 @@
|
||||
(defn /= [a b]
|
||||
(not (= (the Char a) b)))
|
||||
|
||||
(doc lower-case? "Tests whether a character is lower case.")
|
||||
(doc lower-case? "tests whether a character is lower case.")
|
||||
(defn lower-case? [c]
|
||||
(and (<= \a c) (<= c \z)))
|
||||
|
||||
(doc upper-case? "Tests whether a character is upper case.")
|
||||
(doc upper-case? "tests whether a character is upper case.")
|
||||
(defn upper-case? [c]
|
||||
(and (<= \A c) (<= c \Z)))
|
||||
)
|
||||
|
@ -25,22 +25,24 @@
|
||||
@"bg-cyan" @"46"
|
||||
@"bg-white" @"47"})
|
||||
|
||||
(doc color "Generates ANSI coloration.")
|
||||
(doc color "generates ANSI coloration based on a color name `cname`.")
|
||||
(defn color [cname]
|
||||
(let [n (Map.get &table cname)]
|
||||
(String.append "\x1b[" &(String.append &n "m"))))
|
||||
|
||||
(doc colorize "Wraps a string in ANSI coloration and prints it.")
|
||||
(doc colorize "wraps a string `s` in ANSI coloration based on a color name `cname` and prints it.
|
||||
|
||||
It will reset the color afterwards.")
|
||||
(defn colorize [cname s]
|
||||
(String.append &(color cname) &(String.append s &(color "reset"))))
|
||||
)
|
||||
|
||||
(defmodule IO
|
||||
(doc color "Sets the output color using ANSI.")
|
||||
(doc color "sets the output color using ANSI coloration based on a color name `cname`.")
|
||||
(defn color [cname]
|
||||
(print &(Color.color cname)))
|
||||
|
||||
(doc colorize "Wraps a string in ANSI coloration and prints it.")
|
||||
(doc colorize "wraps a string in ANSI coloration based on a color name `cname` and prints it.")
|
||||
(defn colorize [cname s]
|
||||
(print &(Color.colorize cname s)))
|
||||
)
|
||||
|
@ -2,7 +2,9 @@
|
||||
|
||||
(defmodule Debug
|
||||
|
||||
(doc sanitize-addresses "Instruct the compiler to sanitize addresses.")
|
||||
(doc sanitize-addresses "instructs the compiler to sanitize addresses.
|
||||
|
||||
This might not work on all compilers, but reasonably new versions of GCC and Clang are supported.")
|
||||
(defdynamic sanitize-addresses []
|
||||
(add-cflag "-fsanitize=address"))
|
||||
|
||||
@ -10,14 +12,14 @@
|
||||
(register reset-memory-balance! (Fn [] ()))
|
||||
(register log-memory-balance! (Fn [Bool] ()))
|
||||
|
||||
(doc memory-logged "Log all calls to memory allocation within te form. Requires compiling with --log-memory.")
|
||||
(doc memory-logged "logs all calls to memory allocation within the form. Requires the flag `--log-memory` to be passed during compilation.")
|
||||
(defmacro memory-logged [form]
|
||||
(list 'do
|
||||
'(Debug.log-memory-balance! true)
|
||||
form
|
||||
'(Debug.log-memory-balance! false)))
|
||||
|
||||
(doc assert-balanced "Raises an error if the memory balance (numberr of alloc:s - number of free:s) isn't 0. Requires compiling with --log-memory.")
|
||||
(doc assert-balanced "raises an error if the memory balance (number of `alloc`s - number of `free`s) isn't `0`. Requires the flag `--log-memory` to be passed durng compilation.")
|
||||
(defmacro assert-balanced [form]
|
||||
(list 'let '[balance (Debug.memory-balance)]
|
||||
(list 'do
|
||||
@ -29,14 +31,14 @@
|
||||
(System.exit 1)))
|
||||
())))
|
||||
|
||||
(doc trace "Print the value of an expression to stdout, then return its value.")
|
||||
(doc trace "prints the value of an expression to `stdout`, then returns its value.")
|
||||
(defmacro trace [x]
|
||||
(list 'let-do (array 'tmp x)
|
||||
(list 'IO.println (list 'ref (list 'fmt "%s:%d:%d: %s" (file x) (line x) (column x) '&(str tmp))))
|
||||
'tmp)
|
||||
)
|
||||
|
||||
(doc leak-array "Leak some memory. Useful for testing tools that detect leaks.")
|
||||
(doc leak-array "leaks some memory. This function is useful for testing tools that detect leaks.")
|
||||
(register leak-array (Fn [a] ()) "Debug_leak_MINUS_array")
|
||||
|
||||
)
|
||||
|
@ -49,7 +49,9 @@
|
||||
min
|
||||
val)))
|
||||
|
||||
(doc approx "checks whether x and y are approximately (i.e. margin of error of 0.00001) equal")
|
||||
(doc approx "checks whether `x` and `y` are approximately equal.
|
||||
|
||||
The margin of error is `0.00001`.")
|
||||
(defn approx [x y]
|
||||
(if (> x y)
|
||||
(< (- x y) 0.00001)
|
||||
@ -58,6 +60,7 @@
|
||||
(defn /= [x y]
|
||||
(not (Double.= x y)))
|
||||
|
||||
(doc zero "returns the value `0.0`.")
|
||||
(defn zero []
|
||||
0.0)
|
||||
|
||||
|
@ -2,11 +2,17 @@
|
||||
|
||||
(use Array)
|
||||
|
||||
(doc dir-from-path "Removes the file-name part of a path to a file.")
|
||||
(doc dir-from-path "removes the file name part of a path to a file, similar to the `basename` utility in Shell scripting.")
|
||||
(defn dir-from-path [path]
|
||||
(let [segments (split-by path &[\/])
|
||||
n (dec (length &segments))
|
||||
without-last (prefix-array &segments n)]
|
||||
(concat &(copy-map &(fn [s] (str* s "/")) &without-last))))
|
||||
|
||||
(doc file-from-path "removes the base name part of a path to a file, similar to the `filename` utility in Shell scripting.")
|
||||
(defn file-from-path [path]
|
||||
(let [segments (split-by path &[\/])]
|
||||
; this is actually safe here, because split by will return an array of
|
||||
; length > 0
|
||||
(unsafe-last &segments)))
|
||||
)
|
||||
|
@ -25,7 +25,9 @@
|
||||
min
|
||||
val)))
|
||||
|
||||
(doc approx "checks whether x and y are approximately (i.e. margin of error of 0.00001) equal")
|
||||
(doc approx "checks whether `x` and `y` are approximately equal.
|
||||
|
||||
The margin of error is 0.00001.")
|
||||
(defn approx [x y]
|
||||
(if (> x y)
|
||||
(< (- x y) 0.00001f)
|
||||
@ -55,6 +57,7 @@
|
||||
(register copy (Fn [(Ref Float)] Float))
|
||||
(register abs (Fn [Float] Float))
|
||||
|
||||
(doc zero "returns `0.0f`.")
|
||||
(defn zero []
|
||||
0.0f)
|
||||
|
||||
|
@ -23,6 +23,6 @@
|
||||
(fmt-internal (String.substring s (+ (inc idx) next) len)
|
||||
(cdr args)))))))))))
|
||||
|
||||
(doc fmt "fmt formats a string. It supports all of the string interpolations defined in format of the type that should be interpolated (e.g. %d and %x on integers).")
|
||||
(doc fmt "formats a string. It supports all of the string interpolations defined in format of the type that should be interpolated (e.g. %d and %x on integers).")
|
||||
(defmacro fmt [s :rest args]
|
||||
(fmt-internal s args))
|
||||
|
@ -1,9 +1,9 @@
|
||||
(defmodule Geometry
|
||||
(doc degree-to-radians "Converts degrees expressed as a double into radians.")
|
||||
(doc degree-to-radians "converts degrees expressed as a double `n` into radians.")
|
||||
(defn degree-to-radians [n]
|
||||
(Double.* n (Double./ Double.pi 180.0)))
|
||||
|
||||
(doc radians-to-degree "Converts radians expressed as a double into degree.")
|
||||
(doc radians-to-degree "converts radians expressed as a double `n` into degrees.")
|
||||
(defn radians-to-degree [n]
|
||||
(Double.* n (Double./ 180.0 Double.pi)))
|
||||
)
|
||||
|
37
test/filepath.carp
Normal file
37
test/filepath.carp
Normal file
@ -0,0 +1,37 @@
|
||||
(load "Filepath.carp")
|
||||
(load "Test.carp")
|
||||
|
||||
(use-all Test Filepath)
|
||||
|
||||
(deftest test
|
||||
(assert-equal test
|
||||
"test.h"
|
||||
&(file-from-path "/an/absolute/path/for/test.h")
|
||||
"file-from-path works with non-empty paths"
|
||||
)
|
||||
(assert-equal test
|
||||
"."
|
||||
&(file-from-path ".")
|
||||
"file-from-path works with relative paths"
|
||||
)
|
||||
(assert-equal test
|
||||
""
|
||||
&(file-from-path "")
|
||||
"file-from-path works with empty paths"
|
||||
)
|
||||
(assert-equal test
|
||||
"/an/absolute/path/for/"
|
||||
&(dir-from-path "/an/absolute/path/for/test.h")
|
||||
"dir-from-path works with non-empty paths"
|
||||
)
|
||||
(assert-equal test
|
||||
""
|
||||
&(dir-from-path ".")
|
||||
"dir-from-path works with relative paths"
|
||||
)
|
||||
(assert-equal test
|
||||
""
|
||||
&(dir-from-path "")
|
||||
"dir-from-path works with empty paths"
|
||||
)
|
||||
)
|
Loading…
Reference in New Issue
Block a user