Generic primitive array backed array-lists. The pure clojure implementations are a bit slower than the java ones but far less code so these are used for the less-frequently-used primive datatypes - byte, short, char, and float.
Generic primitive array backed array-lists. The pure clojure implementations are a bit slower than the java ones but *far* less code so these are used for the less-frequently-used primive datatypes - byte, short, char, and float.
Fast mutable and immutable associative data structures based on bitmap trie
hashmaps. Mutable pathways implement the java.util.Map or Set interfaces
including in-place update features such as compute or computeIfPresent.
Mutable maps or sets can be turned into their immutable counterparts via the
Clojure persistent! call. This allows working in a mutable space for
convenience and performance then switching to an immutable pathway when
necessary. Note: after persistent! one should never backdoor mutate map or
set again as this will break the contract of immutability. Immutable
data structures also support conversion to transient via transient.
Map keysets (.keySet) are full PersistentHashSets of keys.
Maps and sets support metadata but setting the metadata on mutable objects
returns a new mutable object that shares the backing store leading to possible
issues. Metadata is transferred to the persistent versions of the
mutable/transient objects upon persistent!.
Very fast versions of union, difference and intersection are provided for maps
and sets with the map version of union and difference requiring an extra
argument, a java.util.BiFunction or an IFn taking 2 arguments to merge the
left and right sides into the final map. These implementations of union,
difference, and intersection are the fastest implementation of these
operations we know of on the JVM.
Additionally a fast value update pathway is provided, enabling quickly updating all the values in a given map. Additionally, a new map primitive
mapmap - allows transforming a given map into a new map quickly by
mapping across all the entries.Unlike the standard Java objects, mutation-via-iterator is not supported.
Fast mutable and immutable associative data structures based on bitmap trie hashmaps. Mutable pathways implement the `java.util.Map` or `Set` interfaces including in-place update features such as compute or computeIfPresent. Mutable maps or sets can be turned into their immutable counterparts via the Clojure `persistent!` call. This allows working in a mutable space for convenience and performance then switching to an immutable pathway when necessary. Note: after `persistent!` one should never backdoor mutate map or set again as this will break the contract of immutability. Immutable data structures also support conversion to transient via `transient`. Map keysets (`.keySet`) are full `PersistentHashSet`s of keys. Maps and sets support metadata but setting the metadata on mutable objects returns a new mutable object that shares the backing store leading to possible issues. Metadata is transferred to the persistent versions of the mutable/transient objects upon `persistent!`. Very fast versions of union, difference and intersection are provided for maps and sets with the map version of union and difference requiring an extra argument, a `java.util.BiFunction` or an `IFn` taking 2 arguments to merge the left and right sides into the final map. These implementations of union, difference, and intersection are the fastest implementation of these operations we know of on the JVM. Additionally a fast value update pathway is provided, enabling quickly updating all the values in a given map. Additionally, a new map primitive - [[mapmap]] - allows transforming a given map into a new map quickly by mapping across all the entries. Unlike the standard Java objects, mutation-via-iterator is not supported.
Simple fast bloom filter based on apache parquet BlockSplitBloomFilter.
Simple fast bloom filter based on apache parquet BlockSplitBloomFilter.
Alternative protocol implementation.
Major features:
Allows subclasses to override only a subset of the methods and if the superclass has overridden the method then the superclasses implementation will be used.
Supports primitive typehints on function arguments and return values.
Much higher and more predictable multithreaded performance for protocol method invocation due to the fewer number of global variables that are read and written to for a single protocol method invocation. Does not write to global variables on a per-call basis meaning far less cpu/cache traffic in high contention scenarios.
Attempting to extend a protocol method that doesn't exist is an error at extension time.
Overriding the protocol for the base object array class overrides it for all things convertible to object array while still allowing the concrete array type to match a specific override.
Another design decision is to avoid the interface check - this simplifes the hot path a slight bit at the cost of slightly slower calltimes in the case the interface is used. For those cases often it is possible to simply typehint the interface and call it directly avoiding any protocol dispatch overhead.
Additional call overhead above and beyond a normal fn invocation in an arm mac is -6ns - the time
for .getClass call into single concurrent hash map lookup.
Alternative protocol implementation. Major features: * Allows subclasses to override only a subset of the methods and if the superclass has overridden the method then the superclasses implementation will be used. * Supports primitive typehints on function arguments and return values. * Much higher and more predictable multithreaded performance for protocol method invocation due to the fewer number of global variables that are read and written to for a single protocol method invocation. Does not write to global variables on a per-call basis meaning far less cpu/cache traffic in high contention scenarios. * Attempting to extend a protocol method that doesn't exist is an error at extension time. * Overriding the protocol for the base object array class overrides it for all things convertible to object array while still allowing the concrete array type to match a specific override. Another design decision is to avoid the interface check - this simplifes the hot path a slight bit at the cost of slightly slower calltimes in the case the interface is used. For those cases often it is possible to simply typehint the interface and call it directly avoiding any protocol dispatch overhead. Additional call overhead above and beyond a normal fn invocation in an arm mac is `-6ns` - the time for `.getClass` call into single concurrent hash map lookup.
Helpers for working with java.util.function package objects.
Helpers for working with [java.util.function](https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html) package objects.
Extensible let to allow efficient typed destructuring.
Registered Extensions:
dbls and lngs will most efficiently destructure java primitive arrays and fall back to casting the result
of clojure.lang.RT/nth if input is not a double or long array.
dlb-fns and lng-fns call the object's IFn interface with no interface checking. This will not work
with a raw array but is the fastest way - faster than RT/nth - to get data out of a persistent-vector or map
like object.
obj-fns - fast IFn-based destructuring to objects - does not work with object arrays. Often much faster
than RT/nth.
This can significantly reduce boxing in tight loops without needing to result in really verbose pathways.
user> (h/let [[a b] (dbls [1 2])] (+ a b))
3.0
user> (hamf/sum-fast (lznc/cartesian-map
#(h/let [[a b c d](lng-fns %)]
(-> (+ a b) (+ c) (+ d)))
[1 2 3]
[4 5 6]
[7 8 9]
[10 11 12 13 14]))
3645.0
See also ham-fisted.primitive-invoke, ham-fisted.api/dnth ham-fisted.api/lnth.
Extensible let to allow efficient typed destructuring.
Registered Extensions:
`dbls` and `lngs` will most efficiently destructure java primitive arrays and fall back to casting the result
of clojure.lang.RT/nth if input is not a double or long array.
`dlb-fns` and `lng-fns` call the object's IFn interface with no interface checking. This will *not* work
with a raw array but is the fastest way - faster than RT/nth - to get data out of a persistent-vector or map
like object.
`obj-fns` - fast IFn-based destructuring to objects - does not work with object arrays. Often much faster
than RT/nth.
This can significantly reduce boxing in tight loops without needing to result in really verbose pathways.
```clojure
user> (h/let [[a b] (dbls [1 2])] (+ a b))
3.0
user> (hamf/sum-fast (lznc/cartesian-map
#(h/let [[a b c d](lng-fns %)]
(-> (+ a b) (+ c) (+ d)))
[1 2 3]
[4 5 6]
[7 8 9]
[10 11 12 13 14]))
3645.0
```
See also [[ham-fisted.primitive-invoke]], [[ham-fisted.api/dnth]] [[ham-fisted.api/lnth]].Generialized efficient pathways involving iterators.
Generialized efficient pathways involving iterators.
Lazy, noncaching implementation of many clojure.core functions. There are several benefits of carefully constructed lazy noncaching versions:
Lazy, noncaching implementation of many clojure.core functions. There are several benefits of carefully
constructed lazy noncaching versions:
1. No locking - better multithreading/green thread performance.
2. Higher performance generally.
3. More datatype flexibility - if map is passed a single randomly addressible or generically
parallelizable container the result is still randomly addressible or generically perallelizable.
For instance (map key {:a 1 :b 2}) returns in the generic case something that can still be parallelizable
as the entry set of a map implements spliterator.Functions for working with java's mutable map interface
Functions for working with java's mutable map interface
For statically traced calls the Clojure compiler calls the primitive version of type-hinted functions and this makes quite a difference in tight loops. Often times, however, functions are passed by values or returned from if-statements and then you need to explicitly call the primitive overload - this makes that pathway less verbose. Functions must first be check-casted to their primitive types and then calling them will use their primitive overloads avoiding all casting.
(defn doit [f x y]
(let [f (pi/->ddd f)]
(loop [x x y y]
(if (< x y)
(recur (pi/ddd f x y) y)
x))))
For statically traced calls the Clojure compiler calls the primitive version of type-hinted functions
and this makes quite a difference in tight loops. Often times, however, functions are passed by values
or returned from if-statements and then you need to explicitly call the primitive overload - this makes
that pathway less verbose. Functions must first be check-casted to their primitive types and then
calling them will use their primitive overloads avoiding all casting.
```clojure
(defn doit [f x y]
(let [f (pi/->ddd f)]
(loop [x x y y]
(if (< x y)
(recur (pi/ddd f x y) y)
x))))
```Protocol-based parallel reduction architecture and helper functions.
Protocol-based parallel reduction architecture and helper functions.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |