ocaml/opam-repository — pull request #1420 by bmillwood (2013-12-11 09:20:56+00:00)
Title: core-109.55.00-rc1

# 109.55.00

## async_extra

- Added `Udp.recvmmsg_no_sources_loop`, a specialization of
`recvmmsg_loop` for improved performance.

This improvement was driven by profiling at high message rates.

## async_unix

- Fixed `Scheduler.is_running` to not initialize the scheduler.
- Added `Writer.make_write`, which is a general function for blitting
directly to a writer's buffer.
- Added `Writer.transfer'`, which is like `Writer.transfer` but allows
async actions in the callback.

This was requested in pull request #1.
- Added `Writer.write_iobuf`, which blits the contents of an iobuf
directly to a writer's buffer.

## core

- Fixed building on FreeBSD and OpenBSD.
- Added `with typerep` to many `Core` types.
- Made `open Core.Std` support `with typerep`.
- Added `Iobuf.recvmmsg_assume_fd_is_nonblocking_no_options`,
a specialization of `recvmmsg_assume_fd_is_nonblocking` for improved
performance.

This improvement was driven by profiling at high message rates.
- Changed `Unix.Rlimit.virtual_memory` be an `Or_error.t`, for platforms
where it is undefined.

## core_bench

- Improved `bench.mli`'s generated docs and added some usage examples.

This also partly satisfies issue #3.
- Added the ability to create groups of benchmarks with a common prefix.

For example, the prefix "Perf" below is created in created using
`create_group`:

```ocaml
let command = Bench.make_command [
Bench.Test.create ~name:"Time.now" (fun () ->
ignore (Time.now ()));

...

Bench.Test.create_group ~name:"Perf" [
Bench.Test.create ~name:"TSC.now" ...
```

and the output shows:

Estimated testing time 7s (7 benchmarks x 1s). Change using -quota SECS.
```
┌───────────────────────────────────────────┬──────────┬─────────┬────────────┐
│ Name │ Time/Run │ mWd/Run │ Percentage │
├───────────────────────────────────────────┼──────────┼─────────┼────────────┤
│ Time.now │ 41.38ns │ 2.00w │ 16.72% │
│ Calibrator.calibrate │ 247.42ns │ 32.00w │ 100.00% │
│ Perf/TSC.now │ 7.84ns │ │ 3.17% │
│ Perf/TSC.to_time │ 9.35ns │ 2.00w │ 3.78% │
│ Perf/TSC.to_time (TSC.now ()) │ 13.22ns │ 2.00w │ 5.34% │
│ Perf/TSC.to_nanos_since_epoch │ 10.83ns │ │ 4.38% │
│ Perf/TSC.to_nanos_since_epoch(TSC.now ()) │ 14.86ns │ │ 6.00% │
└───────────────────────────────────────────┴──────────┴─────────┴────────────┘
```

## core_extended

- Added `Service_command.acquire_lock_exn`, for acquiring a service's lock.

## core_kernel

- Added `with typerep` to many `Core` types.
- Changed `Flat_queue` to raise if the queue is mutated during
iteration.
- Improved `Map.merge` to run in linear time.

## pa_bench

- Added support for inline benchmarks using the `BENCH` syntax, similar
to `TEST`.

This feature allows users to specify inline benchmarks in any library.

One can specify a benchmark using the following syntax:

```ocaml
BENCH "name" = expr
```

In the above, the value of `expr` is ignored. This creates
a benchmark for `expr`, that is run using the
`inline_benchmarks_runner` script from the command-line. This
workflow is similar to that of inline unit tests.

One can specify benchmarks that require some initialization using
`BENCH_FUN`. For example:

```ocaml
BENCH_FUN "name" =
let t = create () in
(fun () -> test_something t)
```

The function returned on the RHS of `BENCH_FUN` should have type `unit
-> unit`. One can specify benchmarks that have a variable parameter
using `BENCH_INDEXED`. For example:

```ocaml
BENCH_INDEXED "Array.create" len [1;10;100;1000] =
(fun () -> Array.create ~len 0)
```

The above snippet measures the time taken to create arrays of
different length. Indexed tests are useful in highlighting
non-linearities in the execution time of functions.

We can group benchmarks together into modules and the output of
`inline_benchmarks_runner` will reflect this grouping.

```ocaml
BENCH_MODULE "Blit tests" = struct

..some benchmarks..

end
```

For examples of all of the above see `core_gc.ml` and `core_array.ml`.

Only the generated `inline_benchmarks_runner.exe` depends on
`Core_bench` and other libraries. The library that includes the the
benchmarks itself does not have a dependency on `Core_bench`. Doing
this is important so that we can add benchmarks to `Core` and still
avoid cyclic dependencies. Finally, it is important to note that
adding inline benchmarks should have little effect on the execution or
module initialization time.