merge(3p/immer): Subtree merge at 'ad3e3556d' as 'third_party/immer'
Change-Id: I9636a41ad44b4218293833fd3e9456d9b07c731b
This commit is contained in:
commit
1213b086a1
311 changed files with 74223 additions and 0 deletions
4
third_party/immer/tools/clojure/README.md
vendored
Normal file
4
third_party/immer/tools/clojure/README.md
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
|
||||
```
|
||||
lein run
|
||||
```
|
12
third_party/immer/tools/clojure/project.clj
vendored
Normal file
12
third_party/immer/tools/clojure/project.clj
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
(defproject immer-benchmarks "0.1.0-SNAPSHOT"
|
||||
:description "Benchmarks for immutable data structures"
|
||||
:url "http://example.com/FIXME"
|
||||
:dependencies [[org.clojure/clojure "1.8.0"]
|
||||
[org.clojure/core.rrb-vector "0.0.11"]
|
||||
[criterium "0.4.4"]]
|
||||
:plugins [[lein-git-deps "0.0.1-SNAPSHOT"]]
|
||||
;;:git-dependencies [["https://github.com/clojure/core.rrb-vector.git"]]
|
||||
:source-paths [;;".lein-git-deps/core.rrb-vector/src/main/clojure"
|
||||
"src"]
|
||||
|
||||
:main immer-benchmark)
|
131
third_party/immer/tools/clojure/src/immer_benchmark.clj
vendored
Normal file
131
third_party/immer/tools/clojure/src/immer_benchmark.clj
vendored
Normal file
|
@ -0,0 +1,131 @@
|
|||
(ns immer-benchmark
|
||||
(:require [criterium.core :as c]
|
||||
[clojure.core.rrb-vector :as fv]))
|
||||
|
||||
(defn h0 [& args]
|
||||
(apply println "\n####" args))
|
||||
|
||||
(defn h1 [& args]
|
||||
(apply println "\n====" args))
|
||||
|
||||
(defn h2 [& args]
|
||||
(apply println "\n----" args))
|
||||
|
||||
(defn run-benchmarks [N S]
|
||||
(h0 "Running benchmarks: N =" N " S =" S)
|
||||
|
||||
(def c-steps 10)
|
||||
|
||||
(defn vector-push-f [v]
|
||||
(loop [v v
|
||||
i 0]
|
||||
(if (< i N)
|
||||
(recur (fv/catvec (fv/vector i) v)
|
||||
(inc i))
|
||||
v)))
|
||||
|
||||
(defn vector-push [v]
|
||||
(loop [v v
|
||||
i 0]
|
||||
(if (< i N)
|
||||
(recur (conj v i)
|
||||
(inc i))
|
||||
v)))
|
||||
|
||||
(defn vector-push! [v]
|
||||
(loop [v (transient v)
|
||||
i 0]
|
||||
(if (< i N)
|
||||
(recur (conj! v i)
|
||||
(inc i))
|
||||
(persistent! v))))
|
||||
|
||||
(defn vector-concat [v vc]
|
||||
(loop [v v
|
||||
i 0]
|
||||
(if (< i c-steps)
|
||||
(recur (fv/catvec v vc)
|
||||
(inc i))
|
||||
v)))
|
||||
|
||||
(defn vector-update [v]
|
||||
(loop [v v
|
||||
i 0]
|
||||
(if (< i N)
|
||||
(recur (assoc v i (+ i 1))
|
||||
(inc i))
|
||||
v)))
|
||||
|
||||
(defn vector-update-random [v]
|
||||
(loop [v v
|
||||
i 0]
|
||||
(if (< i N)
|
||||
(recur (assoc v (rand-int N) i)
|
||||
(inc i))
|
||||
v)))
|
||||
|
||||
(defn vector-update! [v]
|
||||
(loop [v (transient v)
|
||||
i 0]
|
||||
(if (< i N)
|
||||
(recur (assoc! v i (+ i 1))
|
||||
(inc i))
|
||||
(persistent! v))))
|
||||
|
||||
(defn vector-update-random! [v]
|
||||
(loop [v (transient v)
|
||||
i 0]
|
||||
(if (< i N)
|
||||
(recur (assoc! v (rand-int N) i)
|
||||
(inc i))
|
||||
(persistent! v))))
|
||||
|
||||
(defn vector-iter [v]
|
||||
(reduce + 0 v))
|
||||
|
||||
(defn the-benchmarks [empty-v]
|
||||
(def full-v (into empty-v (range N)))
|
||||
(h2 "iter")
|
||||
(c/bench (vector-iter full-v) :samples S)
|
||||
(if (> N 100000)
|
||||
(h2 "skipping updates 'cuz N > 100000 (would run out of mem)")
|
||||
(do
|
||||
(h2 "update!")
|
||||
(c/bench (vector-update! full-v) :samples S)
|
||||
(h2 "update-random!")
|
||||
(c/bench (vector-update-random! full-v) :samples S)
|
||||
(h2 "push!")
|
||||
(c/bench (vector-push! empty-v) :samples S)
|
||||
(h2 "update")
|
||||
(c/bench (vector-update full-v) :samples S)
|
||||
(h2 "update-random")
|
||||
(c/bench (vector-update-random full-v) :samples S)
|
||||
(h2 "push")
|
||||
(c/bench (vector-push empty-v) :samples S))))
|
||||
|
||||
(defn the-rrb-benchmarks [empty-v]
|
||||
(if (> N 1000)
|
||||
(h2 "skipping relaxed test 'cuz N > 1000 (rrb-vector bug)")
|
||||
(do
|
||||
(def full-v (vector-push-f empty-v))
|
||||
(h2 "iter/f")
|
||||
(c/bench (vector-iter full-v) :samples S)
|
||||
(h2 "update/f")
|
||||
(c/bench (vector-update full-v) :samples S)
|
||||
(h2 "update-random/f")
|
||||
(c/bench (vector-update-random full-v) :samples S)))
|
||||
(def short-v (into empty-v (range (/ N c-steps))))
|
||||
(h2 "concat")
|
||||
(c/bench (vector-concat empty-v short-v)) :samples S)
|
||||
|
||||
(h1 "vector")
|
||||
(the-benchmarks (vector))
|
||||
|
||||
(h1 "rrb-vector")
|
||||
(the-benchmarks (fv/vector))
|
||||
(the-rrb-benchmarks (fv/vector)))
|
||||
|
||||
(defn -main []
|
||||
(run-benchmarks 1000 100)
|
||||
(run-benchmarks 100000 20)
|
||||
(run-benchmarks 10000000 3))
|
77
third_party/immer/tools/docker/icfp17/Dockerfile
vendored
Normal file
77
third_party/immer/tools/docker/icfp17/Dockerfile
vendored
Normal file
|
@ -0,0 +1,77 @@
|
|||
FROM debian:stretch
|
||||
|
||||
MAINTAINER arximboldi
|
||||
|
||||
## install immer
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y git
|
||||
RUN git clone https://github.com/arximboldi/immer.git
|
||||
|
||||
## prepare test dependencies
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y \
|
||||
autoconf \
|
||||
automake \
|
||||
cmake \
|
||||
g++ \
|
||||
libboost-dev \
|
||||
libtool \
|
||||
make \
|
||||
pkg-config \
|
||||
--
|
||||
|
||||
RUN mkdir /immer/build
|
||||
WORKDIR /immer/build
|
||||
RUN cmake .. -DCMAKE_BUILD_TYPE=Release -DCHECK_BENCHMARKS=1
|
||||
RUN make deps
|
||||
RUN make tests examples benchmarks
|
||||
|
||||
## prepare clojure dependencies
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y default-jdk curl
|
||||
|
||||
RUN curl https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein \
|
||||
> /usr/local/bin/lein && \
|
||||
chmod +x /usr/local/bin/lein
|
||||
|
||||
WORKDIR /immer/tools/clojure
|
||||
ENV LEIN_ROOT ok
|
||||
RUN lein deps
|
||||
RUN lein compile
|
||||
|
||||
## prepare scala dependencies
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y gnupg2 apt-transport-https
|
||||
RUN echo "deb https://dl.bintray.com/sbt/debian /" \
|
||||
> /etc/apt/sources.list.d/sbt.list && \
|
||||
apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 \
|
||||
--recv 2EE0EA64E40A89B84B2DF73499E82A75642AC823 && \
|
||||
apt-get update && \
|
||||
apt-get install -y sbt
|
||||
|
||||
WORKDIR /immer/tools/scala
|
||||
RUN sbt compile
|
||||
|
||||
## prepare python dependencies
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y python-pip
|
||||
|
||||
RUN pip install \
|
||||
pytest-benchmark \
|
||||
pyrsistent
|
||||
|
||||
RUN pip install /immer
|
||||
|
||||
## add some editors
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y emacs vim nano
|
||||
|
||||
## go to a useful working dir
|
||||
|
||||
WORKDIR /immer
|
9458
third_party/immer/tools/include/catch.hpp
vendored
Normal file
9458
third_party/immer/tools/include/catch.hpp
vendored
Normal file
File diff suppressed because it is too large
Load diff
5696
third_party/immer/tools/include/doctest.h
vendored
Normal file
5696
third_party/immer/tools/include/doctest.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
4292
third_party/immer/tools/include/nonius.h++
vendored
Normal file
4292
third_party/immer/tools/include/nonius.h++
vendored
Normal file
File diff suppressed because one or more lines are too long
445
third_party/immer/tools/include/prettyprint.hpp
vendored
Normal file
445
third_party/immer/tools/include/prettyprint.hpp
vendored
Normal file
|
@ -0,0 +1,445 @@
|
|||
// Copyright Louis Delacroix 2010 - 2014.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// A pretty printing library for C++
|
||||
//
|
||||
// Usage:
|
||||
// Include this header, and operator<< will "just work".
|
||||
|
||||
#ifndef H_PRETTY_PRINT
|
||||
#define H_PRETTY_PRINT
|
||||
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <set>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <unordered_set>
|
||||
#include <utility>
|
||||
#include <valarray>
|
||||
|
||||
namespace pretty_print
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
// SFINAE type trait to detect whether T::const_iterator exists.
|
||||
|
||||
struct sfinae_base
|
||||
{
|
||||
using yes = char;
|
||||
using no = yes[2];
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct has_const_iterator : private sfinae_base
|
||||
{
|
||||
private:
|
||||
template <typename C> static yes & test(typename C::const_iterator*);
|
||||
template <typename C> static no & test(...);
|
||||
public:
|
||||
static const bool value = sizeof(test<T>(nullptr)) == sizeof(yes);
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct has_begin_end : private sfinae_base
|
||||
{
|
||||
private:
|
||||
template <typename C>
|
||||
static yes & f(typename std::enable_if<
|
||||
std::is_same<decltype(static_cast<typename C::const_iterator(C::*)() const>(&C::begin)),
|
||||
typename C::const_iterator(C::*)() const>::value>::type *);
|
||||
|
||||
template <typename C> static no & f(...);
|
||||
|
||||
template <typename C>
|
||||
static yes & g(typename std::enable_if<
|
||||
std::is_same<decltype(static_cast<typename C::const_iterator(C::*)() const>(&C::end)),
|
||||
typename C::const_iterator(C::*)() const>::value, void>::type*);
|
||||
|
||||
template <typename C> static no & g(...);
|
||||
|
||||
public:
|
||||
static bool const beg_value = sizeof(f<T>(nullptr)) == sizeof(yes);
|
||||
static bool const end_value = sizeof(g<T>(nullptr)) == sizeof(yes);
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
// Holds the delimiter values for a specific character type
|
||||
|
||||
template <typename TChar>
|
||||
struct delimiters_values
|
||||
{
|
||||
using char_type = TChar;
|
||||
const char_type * prefix;
|
||||
const char_type * delimiter;
|
||||
const char_type * postfix;
|
||||
};
|
||||
|
||||
|
||||
// Defines the delimiter values for a specific container and character type
|
||||
|
||||
template <typename T, typename TChar>
|
||||
struct delimiters
|
||||
{
|
||||
using type = delimiters_values<TChar>;
|
||||
static const type values;
|
||||
};
|
||||
|
||||
|
||||
// Functor to print containers. You can use this directly if you want
|
||||
// to specificy a non-default delimiters type. The printing logic can
|
||||
// be customized by specializing the nested template.
|
||||
|
||||
template <typename T,
|
||||
typename TChar = char,
|
||||
typename TCharTraits = ::std::char_traits<TChar>,
|
||||
typename TDelimiters = delimiters<T, TChar>>
|
||||
struct print_container_helper
|
||||
{
|
||||
using delimiters_type = TDelimiters;
|
||||
using ostream_type = std::basic_ostream<TChar, TCharTraits>;
|
||||
|
||||
template <typename U>
|
||||
struct printer
|
||||
{
|
||||
static void print_body(const U & c, ostream_type & stream)
|
||||
{
|
||||
using std::begin;
|
||||
using std::end;
|
||||
|
||||
auto it = begin(c);
|
||||
const auto the_end = end(c);
|
||||
|
||||
if (it != the_end)
|
||||
{
|
||||
for ( ; ; )
|
||||
{
|
||||
stream << *it;
|
||||
|
||||
if (++it == the_end) break;
|
||||
|
||||
if (delimiters_type::values.delimiter != NULL)
|
||||
stream << delimiters_type::values.delimiter;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
print_container_helper(const T & container)
|
||||
: container_(container)
|
||||
{ }
|
||||
|
||||
inline void operator()(ostream_type & stream) const
|
||||
{
|
||||
if (delimiters_type::values.prefix != NULL)
|
||||
stream << delimiters_type::values.prefix;
|
||||
|
||||
printer<T>::print_body(container_, stream);
|
||||
|
||||
if (delimiters_type::values.postfix != NULL)
|
||||
stream << delimiters_type::values.postfix;
|
||||
}
|
||||
|
||||
private:
|
||||
const T & container_;
|
||||
};
|
||||
|
||||
// Specialization for pairs
|
||||
|
||||
template <typename T, typename TChar, typename TCharTraits, typename TDelimiters>
|
||||
template <typename T1, typename T2>
|
||||
struct print_container_helper<T, TChar, TCharTraits, TDelimiters>::printer<std::pair<T1, T2>>
|
||||
{
|
||||
using ostream_type = typename print_container_helper<T, TChar, TCharTraits, TDelimiters>::ostream_type;
|
||||
|
||||
static void print_body(const std::pair<T1, T2> & c, ostream_type & stream)
|
||||
{
|
||||
stream << c.first;
|
||||
if (print_container_helper<T, TChar, TCharTraits, TDelimiters>::delimiters_type::values.delimiter != NULL)
|
||||
stream << print_container_helper<T, TChar, TCharTraits, TDelimiters>::delimiters_type::values.delimiter;
|
||||
stream << c.second;
|
||||
}
|
||||
};
|
||||
|
||||
// Specialization for tuples
|
||||
|
||||
template <typename T, typename TChar, typename TCharTraits, typename TDelimiters>
|
||||
template <typename ...Args>
|
||||
struct print_container_helper<T, TChar, TCharTraits, TDelimiters>::printer<std::tuple<Args...>>
|
||||
{
|
||||
using ostream_type = typename print_container_helper<T, TChar, TCharTraits, TDelimiters>::ostream_type;
|
||||
using element_type = std::tuple<Args...>;
|
||||
|
||||
template <std::size_t I> struct Int { };
|
||||
|
||||
static void print_body(const element_type & c, ostream_type & stream)
|
||||
{
|
||||
tuple_print(c, stream, Int<0>());
|
||||
}
|
||||
|
||||
static void tuple_print(const element_type &, ostream_type &, Int<sizeof...(Args)>)
|
||||
{
|
||||
}
|
||||
|
||||
static void tuple_print(const element_type & c, ostream_type & stream,
|
||||
typename std::conditional<sizeof...(Args) != 0, Int<0>, std::nullptr_t>::type)
|
||||
{
|
||||
stream << std::get<0>(c);
|
||||
tuple_print(c, stream, Int<1>());
|
||||
}
|
||||
|
||||
template <std::size_t N>
|
||||
static void tuple_print(const element_type & c, ostream_type & stream, Int<N>)
|
||||
{
|
||||
if (print_container_helper<T, TChar, TCharTraits, TDelimiters>::delimiters_type::values.delimiter != NULL)
|
||||
stream << print_container_helper<T, TChar, TCharTraits, TDelimiters>::delimiters_type::values.delimiter;
|
||||
|
||||
stream << std::get<N>(c);
|
||||
|
||||
tuple_print(c, stream, Int<N + 1>());
|
||||
}
|
||||
};
|
||||
|
||||
// Prints a print_container_helper to the specified stream.
|
||||
|
||||
template<typename T, typename TChar, typename TCharTraits, typename TDelimiters>
|
||||
inline std::basic_ostream<TChar, TCharTraits> & operator<<(
|
||||
std::basic_ostream<TChar, TCharTraits> & stream,
|
||||
const print_container_helper<T, TChar, TCharTraits, TDelimiters> & helper)
|
||||
{
|
||||
helper(stream);
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
// Basic is_container template; specialize to derive from std::true_type for all desired container types
|
||||
|
||||
template <typename T>
|
||||
struct is_container : public std::integral_constant<bool,
|
||||
detail::has_const_iterator<T>::value &&
|
||||
detail::has_begin_end<T>::beg_value &&
|
||||
detail::has_begin_end<T>::end_value> { };
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
struct is_container<T[N]> : std::true_type { };
|
||||
|
||||
template <std::size_t N>
|
||||
struct is_container<char[N]> : std::false_type { };
|
||||
|
||||
template <typename T>
|
||||
struct is_container<std::valarray<T>> : std::true_type { };
|
||||
|
||||
template <typename T1, typename T2>
|
||||
struct is_container<std::pair<T1, T2>> : std::true_type { };
|
||||
|
||||
template <typename ...Args>
|
||||
struct is_container<std::tuple<Args...>> : std::true_type { };
|
||||
|
||||
|
||||
// Default delimiters
|
||||
|
||||
template <typename T> struct delimiters<T, char> { static const delimiters_values<char> values; };
|
||||
template <typename T> const delimiters_values<char> delimiters<T, char>::values = { "[", ", ", "]" };
|
||||
template <typename T> struct delimiters<T, wchar_t> { static const delimiters_values<wchar_t> values; };
|
||||
template <typename T> const delimiters_values<wchar_t> delimiters<T, wchar_t>::values = { L"[", L", ", L"]" };
|
||||
|
||||
|
||||
// Delimiters for (multi)set and unordered_(multi)set
|
||||
|
||||
template <typename T, typename TComp, typename TAllocator>
|
||||
struct delimiters< ::std::set<T, TComp, TAllocator>, char> { static const delimiters_values<char> values; };
|
||||
|
||||
template <typename T, typename TComp, typename TAllocator>
|
||||
const delimiters_values<char> delimiters< ::std::set<T, TComp, TAllocator>, char>::values = { "{", ", ", "}" };
|
||||
|
||||
template <typename T, typename TComp, typename TAllocator>
|
||||
struct delimiters< ::std::set<T, TComp, TAllocator>, wchar_t> { static const delimiters_values<wchar_t> values; };
|
||||
|
||||
template <typename T, typename TComp, typename TAllocator>
|
||||
const delimiters_values<wchar_t> delimiters< ::std::set<T, TComp, TAllocator>, wchar_t>::values = { L"{", L", ", L"}" };
|
||||
|
||||
template <typename T, typename TComp, typename TAllocator>
|
||||
struct delimiters< ::std::multiset<T, TComp, TAllocator>, char> { static const delimiters_values<char> values; };
|
||||
|
||||
template <typename T, typename TComp, typename TAllocator>
|
||||
const delimiters_values<char> delimiters< ::std::multiset<T, TComp, TAllocator>, char>::values = { "{", ", ", "}" };
|
||||
|
||||
template <typename T, typename TComp, typename TAllocator>
|
||||
struct delimiters< ::std::multiset<T, TComp, TAllocator>, wchar_t> { static const delimiters_values<wchar_t> values; };
|
||||
|
||||
template <typename T, typename TComp, typename TAllocator>
|
||||
const delimiters_values<wchar_t> delimiters< ::std::multiset<T, TComp, TAllocator>, wchar_t>::values = { L"{", L", ", L"}" };
|
||||
|
||||
template <typename T, typename THash, typename TEqual, typename TAllocator>
|
||||
struct delimiters< ::std::unordered_set<T, THash, TEqual, TAllocator>, char> { static const delimiters_values<char> values; };
|
||||
|
||||
template <typename T, typename THash, typename TEqual, typename TAllocator>
|
||||
const delimiters_values<char> delimiters< ::std::unordered_set<T, THash, TEqual, TAllocator>, char>::values = { "{", ", ", "}" };
|
||||
|
||||
template <typename T, typename THash, typename TEqual, typename TAllocator>
|
||||
struct delimiters< ::std::unordered_set<T, THash, TEqual, TAllocator>, wchar_t> { static const delimiters_values<wchar_t> values; };
|
||||
|
||||
template <typename T, typename THash, typename TEqual, typename TAllocator>
|
||||
const delimiters_values<wchar_t> delimiters< ::std::unordered_set<T, THash, TEqual, TAllocator>, wchar_t>::values = { L"{", L", ", L"}" };
|
||||
|
||||
template <typename T, typename THash, typename TEqual, typename TAllocator>
|
||||
struct delimiters< ::std::unordered_multiset<T, THash, TEqual, TAllocator>, char> { static const delimiters_values<char> values; };
|
||||
|
||||
template <typename T, typename THash, typename TEqual, typename TAllocator>
|
||||
const delimiters_values<char> delimiters< ::std::unordered_multiset<T, THash, TEqual, TAllocator>, char>::values = { "{", ", ", "}" };
|
||||
|
||||
template <typename T, typename THash, typename TEqual, typename TAllocator>
|
||||
struct delimiters< ::std::unordered_multiset<T, THash, TEqual, TAllocator>, wchar_t> { static const delimiters_values<wchar_t> values; };
|
||||
|
||||
template <typename T, typename THash, typename TEqual, typename TAllocator>
|
||||
const delimiters_values<wchar_t> delimiters< ::std::unordered_multiset<T, THash, TEqual, TAllocator>, wchar_t>::values = { L"{", L", ", L"}" };
|
||||
|
||||
|
||||
// Delimiters for pair and tuple
|
||||
|
||||
template <typename T1, typename T2> struct delimiters<std::pair<T1, T2>, char> { static const delimiters_values<char> values; };
|
||||
template <typename T1, typename T2> const delimiters_values<char> delimiters<std::pair<T1, T2>, char>::values = { "(", ", ", ")" };
|
||||
template <typename T1, typename T2> struct delimiters< ::std::pair<T1, T2>, wchar_t> { static const delimiters_values<wchar_t> values; };
|
||||
template <typename T1, typename T2> const delimiters_values<wchar_t> delimiters< ::std::pair<T1, T2>, wchar_t>::values = { L"(", L", ", L")" };
|
||||
|
||||
template <typename ...Args> struct delimiters<std::tuple<Args...>, char> { static const delimiters_values<char> values; };
|
||||
template <typename ...Args> const delimiters_values<char> delimiters<std::tuple<Args...>, char>::values = { "(", ", ", ")" };
|
||||
template <typename ...Args> struct delimiters< ::std::tuple<Args...>, wchar_t> { static const delimiters_values<wchar_t> values; };
|
||||
template <typename ...Args> const delimiters_values<wchar_t> delimiters< ::std::tuple<Args...>, wchar_t>::values = { L"(", L", ", L")" };
|
||||
|
||||
|
||||
// Type-erasing helper class for easy use of custom delimiters.
|
||||
// Requires TCharTraits = std::char_traits<TChar> and TChar = char or wchar_t, and MyDelims needs to be defined for TChar.
|
||||
// Usage: "cout << pretty_print::custom_delims<MyDelims>(x)".
|
||||
|
||||
struct custom_delims_base
|
||||
{
|
||||
virtual ~custom_delims_base() { }
|
||||
virtual std::ostream & stream(::std::ostream &) = 0;
|
||||
virtual std::wostream & stream(::std::wostream &) = 0;
|
||||
};
|
||||
|
||||
template <typename T, typename Delims>
|
||||
struct custom_delims_wrapper : custom_delims_base
|
||||
{
|
||||
custom_delims_wrapper(const T & t_) : t(t_) { }
|
||||
|
||||
std::ostream & stream(std::ostream & s)
|
||||
{
|
||||
return s << print_container_helper<T, char, std::char_traits<char>, Delims>(t);
|
||||
}
|
||||
|
||||
std::wostream & stream(std::wostream & s)
|
||||
{
|
||||
return s << print_container_helper<T, wchar_t, std::char_traits<wchar_t>, Delims>(t);
|
||||
}
|
||||
|
||||
private:
|
||||
const T & t;
|
||||
};
|
||||
|
||||
template <typename Delims>
|
||||
struct custom_delims
|
||||
{
|
||||
template <typename Container>
|
||||
custom_delims(const Container & c) : base(new custom_delims_wrapper<Container, Delims>(c)) { }
|
||||
|
||||
std::unique_ptr<custom_delims_base> base;
|
||||
};
|
||||
|
||||
template <typename TChar, typename TCharTraits, typename Delims>
|
||||
inline std::basic_ostream<TChar, TCharTraits> & operator<<(std::basic_ostream<TChar, TCharTraits> & s, const custom_delims<Delims> & p)
|
||||
{
|
||||
return p.base->stream(s);
|
||||
}
|
||||
|
||||
|
||||
// A wrapper for a C-style array given as pointer-plus-size.
|
||||
// Usage: std::cout << pretty_print_array(arr, n) << std::endl;
|
||||
|
||||
template<typename T>
|
||||
struct array_wrapper_n
|
||||
{
|
||||
typedef const T * const_iterator;
|
||||
typedef T value_type;
|
||||
|
||||
array_wrapper_n(const T * const a, size_t n) : _array(a), _n(n) { }
|
||||
inline const_iterator begin() const { return _array; }
|
||||
inline const_iterator end() const { return _array + _n; }
|
||||
|
||||
private:
|
||||
const T * const _array;
|
||||
size_t _n;
|
||||
};
|
||||
|
||||
|
||||
// A wrapper for hash-table based containers that offer local iterators to each bucket.
|
||||
// Usage: std::cout << bucket_print(m, 4) << std::endl; (Prints bucket 5 of container m.)
|
||||
|
||||
template <typename T>
|
||||
struct bucket_print_wrapper
|
||||
{
|
||||
typedef typename T::const_local_iterator const_iterator;
|
||||
typedef typename T::size_type size_type;
|
||||
|
||||
const_iterator begin() const
|
||||
{
|
||||
return m_map.cbegin(n);
|
||||
}
|
||||
|
||||
const_iterator end() const
|
||||
{
|
||||
return m_map.cend(n);
|
||||
}
|
||||
|
||||
bucket_print_wrapper(const T & m, size_type bucket) : m_map(m), n(bucket) { }
|
||||
|
||||
private:
|
||||
const T & m_map;
|
||||
const size_type n;
|
||||
};
|
||||
|
||||
} // namespace pretty_print
|
||||
|
||||
|
||||
// Global accessor functions for the convenience wrappers
|
||||
|
||||
template<typename T>
|
||||
inline pretty_print::array_wrapper_n<T> pretty_print_array(const T * const a, size_t n)
|
||||
{
|
||||
return pretty_print::array_wrapper_n<T>(a, n);
|
||||
}
|
||||
|
||||
template <typename T> pretty_print::bucket_print_wrapper<T>
|
||||
bucket_print(const T & m, typename T::size_type n)
|
||||
{
|
||||
return pretty_print::bucket_print_wrapper<T>(m, n);
|
||||
}
|
||||
|
||||
|
||||
// Main magic entry point: An overload snuck into namespace std.
|
||||
// Can we do better?
|
||||
|
||||
namespace std
|
||||
{
|
||||
// Prints a container to the stream using default delimiters
|
||||
|
||||
template<typename T, typename TChar, typename TCharTraits>
|
||||
inline typename enable_if< ::pretty_print::is_container<T>::value,
|
||||
basic_ostream<TChar, TCharTraits> &>::type
|
||||
operator<<(basic_ostream<TChar, TCharTraits> & stream, const T & container)
|
||||
{
|
||||
return stream << ::pretty_print::print_container_helper<T, TChar, TCharTraits>(container);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif // H_PRETTY_PRINT
|
25
third_party/immer/tools/reproduce-paper-results.bash
vendored
Executable file
25
third_party/immer/tools/reproduce-paper-results.bash
vendored
Executable file
|
@ -0,0 +1,25 @@
|
|||
#!/bin/bash
|
||||
|
||||
test -d build || mkdir -p build
|
||||
cd build
|
||||
|
||||
cmake .. \
|
||||
-DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-O3 -march=native" \
|
||||
-DCHECK_BENCHMARKS=1 \
|
||||
-DBENCHMARK_PARAM="N:1000" -DBENCHMARK_SAMPLES="100"
|
||||
make benchmarks -j1
|
||||
ctest -R "benchmark/vector-paper*"
|
||||
|
||||
cmake ..\
|
||||
-DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-O3 -march=native" \
|
||||
-DCHECK_BENCHMARKS=1 \
|
||||
-DBENCHMARK_PARAM="N:100000" -DBENCHMARK_SAMPLES="20"
|
||||
make benchmarks -j1
|
||||
ctest -R "benchmark/vector-paper*"
|
||||
|
||||
cmake .. \
|
||||
-DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-O3 -march=native" \
|
||||
-DCHECK_BENCHMARKS=1 \
|
||||
-DBENCHMARK_PARAM="N:10000000" -DBENCHMARK_SAMPLES="3"
|
||||
make benchmarks -j1
|
||||
ctest -R "benchmark/vector-paper*"
|
6
third_party/immer/tools/scala/README.md
vendored
Normal file
6
third_party/immer/tools/scala/README.md
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
|
||||
```
|
||||
# sbt
|
||||
> test
|
||||
> test-only org.immer.* -- -verbose
|
||||
```
|
27
third_party/immer/tools/scala/build.sbt
vendored
Normal file
27
third_party/immer/tools/scala/build.sbt
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
/** This is the simplest possible use of ScalaMeter.
|
||||
* It allows running ScalaMeter benchmarks as part of the test suite.
|
||||
* It means, that when the test command is run, ScalaMeter benchmarks are run along
|
||||
* the tests from other test frameworks, such as ScalaTest or ScalaCheck.
|
||||
*/
|
||||
lazy val basic = Project(
|
||||
"basic",
|
||||
file("."),
|
||||
settings = Defaults.coreDefaultSettings ++ Seq(
|
||||
name := "immer-bechmarks",
|
||||
organization := "org.immer",
|
||||
scalaVersion := "2.11.1",
|
||||
scalacOptions ++= Seq("-deprecation", "-unchecked", "-feature", "-Xlint"),
|
||||
publishArtifact := false,
|
||||
libraryDependencies ++= Seq(
|
||||
"com.storm-enroute" %% "scalameter" % "0.8.2" % "test",
|
||||
"io.github.nicolasstucki" %% "scala-rrb-vector" % "0.1.1"
|
||||
),
|
||||
resolvers ++= Seq(
|
||||
"Sonatype OSS Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots",
|
||||
"Sonatype OSS Releases" at "https://oss.sonatype.org/content/repositories/releases"
|
||||
),
|
||||
testFrameworks += new TestFramework("org.scalameter.ScalaMeterFramework"),
|
||||
parallelExecution in Test := false,
|
||||
logBuffered := false
|
||||
)
|
||||
)
|
168
third_party/immer/tools/scala/src/test/scala/org/immer/benchmarks.scala
vendored
Normal file
168
third_party/immer/tools/scala/src/test/scala/org/immer/benchmarks.scala
vendored
Normal file
|
@ -0,0 +1,168 @@
|
|||
package org.immer
|
||||
|
||||
import org.scalameter.api._
|
||||
import scala.collection.immutable.Vector
|
||||
import scala.collection.immutable.rrbvector.RRBVector
|
||||
|
||||
class BenchmarkBase extends Bench.ForkedTime {
|
||||
val runs = 20
|
||||
val size = 1000
|
||||
val step = 10
|
||||
val sizes = Gen.range("size")(size, size, 1)
|
||||
|
||||
//def relaxedV(v : RRBVector[Int], n : Int) : RRBVector[Int] = {
|
||||
// var r = v
|
||||
// for (i <- 0 to n) {
|
||||
// r = (RRBVector.empty[Int] :+ i) ++ r
|
||||
// }
|
||||
// r
|
||||
//}
|
||||
|
||||
var vectors = for { s <- sizes } yield Vector.empty[Int] ++ (0 until s)
|
||||
var rrbvectors = for { s <- sizes } yield RRBVector.empty[Int] ++ (0 until s)
|
||||
//var rrbvectorsF = for { s <- sizes } yield relaxedV(RRBVector.empty[Int], s)
|
||||
var rrbsteps = for { s <- sizes } yield RRBVector.empty[Int] ++ (0 until s / step)
|
||||
}
|
||||
|
||||
class PushBenchmark extends BenchmarkBase {
|
||||
performance of "push" in {
|
||||
measure method "Vector" in { using(sizes) config(exec.benchRuns -> runs) in { s => {
|
||||
var v = Vector.empty[Int]
|
||||
for (a <- 0 to s) {
|
||||
v = v :+ a
|
||||
}
|
||||
v
|
||||
}}}
|
||||
measure method "RRBVector" in { using(sizes) config(exec.benchRuns -> runs) in { s => {
|
||||
var v = RRBVector.empty[Int]
|
||||
for (a <- 0 to s) {
|
||||
v = v :+ a
|
||||
}
|
||||
v
|
||||
}}}
|
||||
}
|
||||
}
|
||||
|
||||
class UpdateBenchmark extends BenchmarkBase {
|
||||
performance of "update" in {
|
||||
measure method "Vector" in { using(vectors) config(exec.benchRuns -> runs) in { v0 => {
|
||||
var v = v0
|
||||
for (a <- 0 to v.size - 1) {
|
||||
v = v.updated(a, a + 1)
|
||||
}
|
||||
v
|
||||
}}}
|
||||
measure method "RRBVector" in { using(rrbvectors) config(exec.benchRuns -> runs) in { v0 => {
|
||||
var v = v0
|
||||
for (a <- 0 to v.size - 1) {
|
||||
v = v.updated(a, a + 1)
|
||||
}
|
||||
v
|
||||
}}}
|
||||
//measure method "RRBVector/relaxed" in { using(rrbvectorsF) config(exec.benchRuns -> runs) in { v0 => {
|
||||
// var v = v0
|
||||
// for (a <- 0 to v.size - 1) {
|
||||
// v = v.updated(a, a + 1)
|
||||
// }
|
||||
// v
|
||||
//}}}
|
||||
}
|
||||
performance of "update/random" in {
|
||||
measure method "Vector" in { using(vectors) config(exec.benchRuns -> runs) in { v0 => {
|
||||
var v = v0
|
||||
var r = new scala.util.Random
|
||||
for (a <- 0 to v.size - 1) {
|
||||
v = v.updated(r.nextInt(v.size), a + 1)
|
||||
}
|
||||
v
|
||||
}}}
|
||||
measure method "RRBVector" in { using(rrbvectors) config(exec.benchRuns -> runs) in { v0 => {
|
||||
var v = v0
|
||||
var r = new scala.util.Random
|
||||
for (a <- 0 to v.size - 1) {
|
||||
v = v.updated(r.nextInt(v.size), a + 1)
|
||||
}
|
||||
v
|
||||
}}}
|
||||
//measure method "RRBVector/relaxed" in { using(rrbvectorsF) config(exec.benchRuns -> runs) in { v0 => {
|
||||
// var v = v0
|
||||
// var r = new scala.util.Random
|
||||
// for (a <- 0 to v.size - 1) {
|
||||
// v = v.updated(r.nextInt(v.size), a + 1)
|
||||
// }
|
||||
// v
|
||||
//}}}
|
||||
}
|
||||
}
|
||||
|
||||
object IterBenchmark extends BenchmarkBase {
|
||||
performance of "access/reduce" in {
|
||||
measure method "Vector" in { using(vectors) config(exec.benchRuns -> runs) in { v => {
|
||||
v.reduceLeft(_ + _)
|
||||
}}}
|
||||
measure method "RRBVector" in { using(rrbvectors) config(exec.benchRuns -> runs) in { v => {
|
||||
v.reduceLeft(_ + _)
|
||||
}}}
|
||||
//measure method "RRBVector/relaxed" in { using(rrbvectorsF) config(exec.benchRuns -> runs) in { v => {
|
||||
// v.reduceLeft(_ + _)
|
||||
//}}}
|
||||
}
|
||||
performance of "access/idx" in {
|
||||
measure method "Vector" in { using(vectors) config(exec.benchRuns -> runs) in { v => {
|
||||
var r = 0
|
||||
for (a <- 0 to v.size - 1) {
|
||||
r += v(a)
|
||||
}
|
||||
r
|
||||
}}}
|
||||
measure method "RRBVector" in { using(rrbvectors) config(exec.benchRuns -> runs) in { v => {
|
||||
var r = 0
|
||||
for (a <- 0 to v.size - 1) {
|
||||
r += v(a)
|
||||
}
|
||||
r
|
||||
}}}
|
||||
//measure method "RRBVector/relaxed" in { using(rrbvectorsF) config(exec.benchRuns -> runs) in { v => {
|
||||
// var r = 0
|
||||
// for (a <- 0 to v.size - 1) {
|
||||
// r += v(a)
|
||||
// }
|
||||
// r
|
||||
//}}}
|
||||
}
|
||||
performance of "access/iter" in {
|
||||
measure method "Vector" in { using(vectors) config(exec.benchRuns -> runs) in { v => {
|
||||
var r = 0
|
||||
for (a <- v) {
|
||||
r += a
|
||||
}
|
||||
r
|
||||
}}}
|
||||
measure method "RRBVector" in { using(rrbvectors) config(exec.benchRuns -> runs) in { v => {
|
||||
var r = 0
|
||||
for (a <- v) {
|
||||
r += a
|
||||
}
|
||||
r
|
||||
}}}
|
||||
//measure method "RRBVector/relaxed" in { using(rrbvectorsF) config(exec.benchRuns -> runs) in { v => {
|
||||
// var r = 0
|
||||
// for (a <- v) {
|
||||
// r += a
|
||||
// }
|
||||
// r
|
||||
//}}}
|
||||
}
|
||||
}
|
||||
|
||||
class ConcatBenchmark extends BenchmarkBase {
|
||||
performance of "concat" in {
|
||||
measure method "RRBVector ++" in { using(rrbsteps) config(exec.benchRuns -> runs) in { v => {
|
||||
var r = RRBVector.empty[Int]
|
||||
for (_ <- 0 to step) {
|
||||
r = r ++ v
|
||||
}
|
||||
r
|
||||
}}}
|
||||
}
|
||||
}
|
1
third_party/immer/tools/scala/version.sbt
vendored
Normal file
1
third_party/immer/tools/scala/version.sbt
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
version in ThisBuild := "0.8.2"
|
1
third_party/immer/tools/sinusoidal-sphinx-theme
vendored
Submodule
1
third_party/immer/tools/sinusoidal-sphinx-theme
vendored
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit b5adfa2a6def8aa55d95dedc4e1bfde214a5e36c
|
BIN
third_party/immer/tools/travis/ssh-key.enc
vendored
Normal file
BIN
third_party/immer/tools/travis/ssh-key.enc
vendored
Normal file
Binary file not shown.
1
third_party/immer/tools/travis/ssh-key.pub
vendored
Normal file
1
third_party/immer/tools/travis/ssh-key.pub
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDBLgrMsYWwjiR/oe2bzg1kr1CGgLYiLrvQIeZw9mv10qF+MS+xpthy4tXxEHHeqkbQ1FsSoo3RaCKnya47LTysT1HE4Qf1TbxY5b1kU9SJ0jGNYejvkdmWzg/wspSCbFi3PGJhctxoks5sJCfVMc/oFwIlFAZALfL3JIRYk8EZv7bnrtA1Il1hPV2ug7ADBWJOXCc8pW4E7X3ZiDnvAZfqZ1QHrcQwy1aA8LVTv5azJg7Db8D90JjuRTlhO1XL7Cg/PGBkP1B3jOW5LRZK8AupnOPTw4kIsIc/i32O/poZPIRbHqYumYqEKBJQ/ggN4rKVXcp0lrMZ6/joslFLMvwr immer
|
5
third_party/immer/tools/with-tee.bash
vendored
Executable file
5
third_party/immer/tools/with-tee.bash
vendored
Executable file
|
@ -0,0 +1,5 @@
|
|||
#!/bin/bash
|
||||
|
||||
echo "${@:2} | tee $1"
|
||||
|
||||
${@:2} | tee $1
|
Loading…
Add table
Add a link
Reference in a new issue