merge(3p/immer): Subtree merge at 'ad3e3556d' as 'third_party/immer'

Change-Id: I9636a41ad44b4218293833fd3e9456d9b07c731b
This commit is contained in:
Vincent Ambo 2020-07-15 08:20:18 +01:00
commit 1213b086a1
311 changed files with 74223 additions and 0 deletions

View file

@ -0,0 +1,4 @@
```
lein run
```

View 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)

View 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))

View 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

File diff suppressed because it is too large Load diff

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

File diff suppressed because one or more lines are too long

View 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

View 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*"

View file

@ -0,0 +1,6 @@
```
# sbt
> test
> test-only org.immer.* -- -verbose
```

27
third_party/immer/tools/scala/build.sbt vendored Normal file
View 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
)
)

View 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
}}}
}
}

View file

@ -0,0 +1 @@
version in ThisBuild := "0.8.2"

@ -0,0 +1 @@
Subproject commit b5adfa2a6def8aa55d95dedc4e1bfde214a5e36c

Binary file not shown.

View 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
View file

@ -0,0 +1,5 @@
#!/bin/bash
echo "${@:2} | tee $1"
${@:2} | tee $1