Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fa60ea1ae6 | |||
| e7d75f9824 | |||
| df62a871f6 | |||
| e5e25a1aca | |||
| 84f12c7c6d | |||
| 7802f86bd6 | |||
| 43afec3b39 | |||
| 2da7ca5338 |
@@ -653,7 +653,7 @@ jobs:
|
|||||||
benchmarks:
|
benchmarks:
|
||||||
if: github.event_name == 'pull_request'
|
if: github.event_name == 'pull_request'
|
||||||
needs: [format-taginfo-docs]
|
needs: [format-taginfo-docs]
|
||||||
runs-on: ubuntu-24.04
|
runs-on: self-hosted
|
||||||
env:
|
env:
|
||||||
CCOMPILER: clang-16
|
CCOMPILER: clang-16
|
||||||
CXXCOMPILER: clang++-16
|
CXXCOMPILER: clang++-16
|
||||||
@@ -664,37 +664,17 @@ jobs:
|
|||||||
GITHUB_REPOSITORY: ${{ github.repository }}
|
GITHUB_REPOSITORY: ${{ github.repository }}
|
||||||
RUN_BIG_BENCHMARK: ${{ contains(github.event.pull_request.labels.*.name, 'Performance') }}
|
RUN_BIG_BENCHMARK: ${{ contains(github.event.pull_request.labels.*.name, 'Performance') }}
|
||||||
steps:
|
steps:
|
||||||
- name: Enable data.osm.pbf cache
|
|
||||||
if: ${{ ! env.RUN_BIG_BENCHMARK }}
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: ~/data.osm.pbf
|
|
||||||
key: v1-data-osm-pbf
|
|
||||||
restore-keys: |
|
|
||||||
v1-data-osm-pbf
|
|
||||||
- name: Enable compiler cache
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: ~/.ccache
|
|
||||||
key: v1-ccache-benchmarks-${{ github.sha }}
|
|
||||||
restore-keys: |
|
|
||||||
v1-ccache-benchmarks-
|
|
||||||
- name: Enable Conan cache
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: ~/.conan
|
|
||||||
key: v1-conan-benchmarks-${{ github.sha }}
|
|
||||||
restore-keys: |
|
|
||||||
v1-conan-benchmarks-
|
|
||||||
- name: Checkout PR Branch
|
- name: Checkout PR Branch
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.head_ref }}
|
ref: ${{ github.head_ref }}
|
||||||
path: pr
|
path: pr
|
||||||
- name: Install dependencies
|
- name: Activate virtualenv
|
||||||
run: |
|
run: |
|
||||||
python3 -m pip install "conan<2.0.0" "requests==2.31.0" "numpy==1.26.4" --break-system-packages
|
python3 -m venv .venv
|
||||||
sudo apt-get update -y && sudo apt-get install ccache
|
source .venv/bin/activate
|
||||||
|
echo PATH=$PATH >> $GITHUB_ENV
|
||||||
|
pip install "conan<2.0.0" "requests==2.31.0" "numpy==1.26.4"
|
||||||
- name: Prepare data
|
- name: Prepare data
|
||||||
run: |
|
run: |
|
||||||
if [ "$RUN_BIG_BENCHMARK" = "true" ]; then
|
if [ "$RUN_BIG_BENCHMARK" = "true" ]; then
|
||||||
@@ -722,50 +702,67 @@ jobs:
|
|||||||
path: base
|
path: base
|
||||||
- name: Build Base Branch
|
- name: Build Base Branch
|
||||||
run: |
|
run: |
|
||||||
|
cd base
|
||||||
|
npm ci --ignore-scripts
|
||||||
|
cd ..
|
||||||
mkdir base/build
|
mkdir base/build
|
||||||
cd base/build
|
cd base/build
|
||||||
cmake -DENABLE_CONAN=ON -DCMAKE_BUILD_TYPE=Release ..
|
cmake -DENABLE_CONAN=ON -DCMAKE_BUILD_TYPE=Release -DENABLE_NODE_BINDINGS=ON ..
|
||||||
make -j$(nproc)
|
make -j$(nproc)
|
||||||
make -j$(nproc) benchmarks
|
make -j$(nproc) benchmarks
|
||||||
cd ..
|
cd ..
|
||||||
make -C test/data
|
make -C test/data
|
||||||
- name: Build PR Branch
|
- name: Build PR Branch
|
||||||
run: |
|
run: |
|
||||||
|
cd pr
|
||||||
|
npm ci --ignore-scripts
|
||||||
|
cd ..
|
||||||
mkdir -p pr/build
|
mkdir -p pr/build
|
||||||
cd pr/build
|
cd pr/build
|
||||||
cmake -DENABLE_CONAN=ON -DCMAKE_BUILD_TYPE=Release ..
|
cmake -DENABLE_CONAN=ON -DCMAKE_BUILD_TYPE=Release -DENABLE_NODE_BINDINGS=ON ..
|
||||||
make -j$(nproc)
|
make -j$(nproc)
|
||||||
make -j$(nproc) benchmarks
|
make -j$(nproc) benchmarks
|
||||||
cd ..
|
cd ..
|
||||||
make -C test/data
|
make -C test/data
|
||||||
# we run benchmarks in tmpfs to avoid impact of disk IO
|
# we run benchmarks in tmpfs to avoid impact of disk IO
|
||||||
- name: Create folder for tmpfs
|
- name: Create folder for tmpfs
|
||||||
run: mkdir -p /opt/benchmarks
|
run: |
|
||||||
|
# if by any chance it was mounted before(e.g. due to previous job failed), unmount it
|
||||||
|
sudo umount ~/benchmarks | true
|
||||||
|
rm -rf ~/benchmarks
|
||||||
|
mkdir -p ~/benchmarks
|
||||||
|
# see https://llvm.org/docs/Benchmarking.html
|
||||||
- name: Run PR Benchmarks
|
- name: Run PR Benchmarks
|
||||||
run: |
|
run: |
|
||||||
sudo mount -t tmpfs -o size=4g none /opt/benchmarks
|
sudo cset shield -c 2-3 -k on
|
||||||
cp -rf pr/build /opt/benchmarks/build
|
sudo mount -t tmpfs -o size=4g none ~/benchmarks
|
||||||
mkdir -p /opt/benchmarks/test
|
cp -rf pr/build ~/benchmarks/build
|
||||||
cp -rf pr/test/data /opt/benchmarks/test/data
|
cp -rf pr/lib ~/benchmarks/lib
|
||||||
cp -rf pr/profiles /opt/benchmarks/profiles
|
mkdir -p ~/benchmarks/test
|
||||||
|
cp -rf pr/test/data ~/benchmarks/test/data
|
||||||
|
cp -rf pr/profiles ~/benchmarks/profiles
|
||||||
|
|
||||||
./pr/scripts/ci/run_benchmarks.sh -f /opt/benchmarks -r $(pwd)/pr_results -s $(pwd)/pr -b /opt/benchmarks/build -o ~/data.osm.pbf -g ~/gps_traces.csv
|
sudo cset shield --exec -- ./pr/scripts/ci/run_benchmarks.sh -f ~/benchmarks -r $(pwd)/pr_results -s $(pwd)/pr -b ~/benchmarks/build -o ~/data.osm.pbf -g ~/gps_traces.csv
|
||||||
sudo umount /opt/benchmarks
|
sudo umount ~/benchmarks
|
||||||
|
sudo cset shield --reset
|
||||||
- name: Run Base Benchmarks
|
- name: Run Base Benchmarks
|
||||||
run: |
|
run: |
|
||||||
sudo mount -t tmpfs -o size=4g none /opt/benchmarks
|
sudo cset shield -c 2-3 -k on
|
||||||
cp -rf base/build /opt/benchmarks/build
|
sudo mount -t tmpfs -o size=4g none ~/benchmarks
|
||||||
mkdir -p /opt/benchmarks/test
|
cp -rf base/build ~/benchmarks/build
|
||||||
cp -rf base/test/data /opt/benchmarks/test/data
|
cp -rf base/lib ~/benchmarks/lib
|
||||||
cp -rf base/profiles /opt/benchmarks/profiles
|
mkdir -p ~/benchmarks/test
|
||||||
|
cp -rf base/test/data ~/benchmarks/test/data
|
||||||
|
cp -rf base/profiles ~/benchmarks/profiles
|
||||||
|
|
||||||
# TODO: remove it when base branch will have this file at needed location
|
# TODO: remove it when base branch will have this file at needed location
|
||||||
if [ ! -f /opt/benchmarks/test/data/portugal_to_korea.json ]; then
|
if [ ! -f ~/benchmarks/test/data/portugal_to_korea.json ]; then
|
||||||
cp base/src/benchmarks/portugal_to_korea.json /opt/benchmarks/test/data/portugal_to_korea.json
|
cp base/src/benchmarks/portugal_to_korea.json ~/benchmarks/test/data/portugal_to_korea.json
|
||||||
fi
|
fi
|
||||||
# we intentionally use scripts from PR branch to be able to update them and see results in the same PR
|
# we intentionally use scripts from PR branch to be able to update them and see results in the same PR
|
||||||
./pr/scripts/ci/run_benchmarks.sh -f /opt/benchmarks -r $(pwd)/base_results -s $(pwd)/pr -b /opt/benchmarks/build -o ~/data.osm.pbf -g ~/gps_traces.csv
|
sudo cset shield --exec -- cset shield --exec -- ./pr/scripts/ci/run_benchmarks.sh -f ~/benchmarks -r $(pwd)/base_results -s $(pwd)/pr -b ~/benchmarks/build -o ~/data.osm.pbf -g ~/gps_traces.csv
|
||||||
sudo umount /opt/benchmarks
|
sudo umount ~/benchmarks
|
||||||
|
sudo cset shield --reset
|
||||||
- name: Post Benchmark Results
|
- name: Post Benchmark Results
|
||||||
run: |
|
run: |
|
||||||
python3 pr/scripts/ci/post_benchmark_results.py base_results pr_results
|
python3 pr/scripts/ci/post_benchmark_results.py base_results pr_results
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# Unreleased
|
# Unreleased
|
||||||
- Changes from 5.27.1
|
- Changes from 5.27.1
|
||||||
- Features
|
- Features
|
||||||
|
- ADDED: Route pedestrians over highway=platform [#6993](https://github.com/Project-OSRM/osrm-backend/pull/6993)
|
||||||
- REMOVED: Remove all core-CH left-overs [#6920](https://github.com/Project-OSRM/osrm-backend/pull/6920)
|
- REMOVED: Remove all core-CH left-overs [#6920](https://github.com/Project-OSRM/osrm-backend/pull/6920)
|
||||||
- ADDED: Add support for a keepalive_timeout flag. [#6674](https://github.com/Project-OSRM/osrm-backend/pull/6674)
|
- ADDED: Add support for a keepalive_timeout flag. [#6674](https://github.com/Project-OSRM/osrm-backend/pull/6674)
|
||||||
- ADDED: Add support for a default_radius flag. [#6575](https://github.com/Project-OSRM/osrm-backend/pull/6575)
|
- ADDED: Add support for a default_radius flag. [#6575](https://github.com/Project-OSRM/osrm-backend/pull/6575)
|
||||||
|
|||||||
@@ -26,7 +26,15 @@ Feature: Foot - Access tags on ways
|
|||||||
| motorway | no | | |
|
| motorway | no | | |
|
||||||
| motorway | no | yes | x |
|
| motorway | no | yes | x |
|
||||||
| motorway | no | no | |
|
| motorway | no | no | |
|
||||||
|
| platform | | | x |
|
||||||
|
| platform | | yes | x |
|
||||||
|
| platform | | no | |
|
||||||
|
| platform | yes | | x |
|
||||||
|
| platform | yes | yes | x |
|
||||||
|
| platform | yes | no | |
|
||||||
|
| platform | no | | |
|
||||||
|
| platform | no | yes | x |
|
||||||
|
| platform | no | no | |
|
||||||
|
|
||||||
Scenario: Foot - Overwriting implied acccess on ways
|
Scenario: Foot - Overwriting implied acccess on ways
|
||||||
Then routability should be
|
Then routability should be
|
||||||
|
|||||||
@@ -11,57 +11,85 @@ namespace node_osrm
|
|||||||
|
|
||||||
struct V8Renderer
|
struct V8Renderer
|
||||||
{
|
{
|
||||||
explicit V8Renderer(const Napi::Env &env, Napi::Value &out) : env(env), out(out) {}
|
explicit V8Renderer(const Napi::Env &env) : env(env) {}
|
||||||
|
|
||||||
void operator()(const osrm::json::String &string) const
|
Napi::Value operator()(const osrm::json::String &string) const
|
||||||
{
|
{
|
||||||
out = Napi::String::New(env, string.value);
|
return Napi::String::New(env, string.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()(const osrm::json::Number &number) const
|
Napi::Value operator()(const osrm::json::Number &number) const
|
||||||
{
|
{
|
||||||
out = Napi::Number::New(env, number.value);
|
return Napi::Number::New(env, number.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()(const osrm::json::Object &object) const
|
Napi::Value operator()(const osrm::json::Object &object) const
|
||||||
{
|
{
|
||||||
Napi::Object obj = Napi::Object::New(env);
|
Napi::Object obj = Napi::Object::New(env);
|
||||||
for (const auto &keyValue : object.values)
|
for (const auto &keyValue : object.values)
|
||||||
{
|
{
|
||||||
Napi::Value child;
|
obj.Set(keyValue.first, visit(*this, keyValue.second));
|
||||||
std::visit(V8Renderer(env, child), keyValue.second);
|
|
||||||
obj.Set(keyValue.first, child);
|
|
||||||
}
|
}
|
||||||
out = obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()(const osrm::json::Array &array) const
|
Napi::Value operator()(const osrm::json::Array &array) const
|
||||||
{
|
{
|
||||||
Napi::Array a = Napi::Array::New(env, array.values.size());
|
Napi::Array a = Napi::Array::New(env, array.values.size());
|
||||||
for (auto i = 0u; i < array.values.size(); ++i)
|
for (auto i = 0u; i < array.values.size(); ++i)
|
||||||
{
|
{
|
||||||
Napi::Value child;
|
a.Set(i, visit(*this, array.values[i]));
|
||||||
std::visit(V8Renderer(env, child), array.values[i]);
|
|
||||||
a.Set(i, child);
|
|
||||||
}
|
}
|
||||||
out = a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()(const osrm::json::True &) const { out = Napi::Boolean::New(env, true); }
|
Napi::Value operator()(const osrm::json::True &) const { return Napi::Boolean::New(env, true); }
|
||||||
|
|
||||||
void operator()(const osrm::json::False &) const { out = Napi::Boolean::New(env, false); }
|
Napi::Value operator()(const osrm::json::False &) const
|
||||||
|
{
|
||||||
|
return Napi::Boolean::New(env, false);
|
||||||
|
}
|
||||||
|
|
||||||
void operator()(const osrm::json::Null &) const { out = env.Null(); }
|
Napi::Value operator()(const osrm::json::Null &) const { return env.Null(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Napi::Value visit(const V8Renderer &renderer, const osrm::json::Value &value) const
|
||||||
|
{
|
||||||
|
switch (value.index())
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
return renderer(std::get<osrm::json::String>(value));
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
return renderer(std::get<osrm::json::Number>(value));
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
return renderer(std::get<osrm::json::Object>(value));
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
return renderer(std::get<osrm::json::Array>(value));
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
return renderer(std::get<osrm::json::True>(value));
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
return renderer(std::get<osrm::json::False>(value));
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
return renderer(std::get<osrm::json::Null>(value));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return env.Null();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const Napi::Env &env;
|
const Napi::Env &env;
|
||||||
Napi::Value &out;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void renderToV8(const Napi::Env &env, Napi::Value &out, const osrm::json::Object &object)
|
inline void renderToV8(const Napi::Env &env, Napi::Value &out, const osrm::json::Object &object)
|
||||||
{
|
{
|
||||||
V8Renderer renderer(env, out);
|
V8Renderer renderer(env);
|
||||||
renderer(object);
|
out = renderer(object);
|
||||||
}
|
}
|
||||||
} // namespace node_osrm
|
} // namespace node_osrm
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#define MEMINFO_HPP
|
#define MEMINFO_HPP
|
||||||
|
|
||||||
#include "util/log.hpp"
|
#include "util/log.hpp"
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
@@ -10,22 +11,31 @@
|
|||||||
namespace osrm::util
|
namespace osrm::util
|
||||||
{
|
{
|
||||||
|
|
||||||
inline void DumpMemoryStats()
|
inline size_t PeakRAMUsedInBytes()
|
||||||
{
|
{
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
rusage usage;
|
rusage usage;
|
||||||
getrusage(RUSAGE_SELF, &usage);
|
getrusage(RUSAGE_SELF, &usage);
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
// Under linux, ru.maxrss is in kb
|
// Under linux, ru.maxrss is in kb
|
||||||
util::Log() << "RAM: peak bytes used: " << usage.ru_maxrss * 1024;
|
return usage.ru_maxrss * 1024;
|
||||||
#else // __linux__
|
#else // __linux__
|
||||||
// Under BSD systems (OSX), it's in bytes
|
// Under BSD systems (OSX), it's in bytes
|
||||||
util::Log() << "RAM: peak bytes used: " << usage.ru_maxrss;
|
return usage.ru_maxrss;
|
||||||
#endif // __linux__
|
#endif // __linux__
|
||||||
|
#else // _WIN32
|
||||||
|
return 0;
|
||||||
|
#endif // _WIN32
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void DumpMemoryStats()
|
||||||
|
{
|
||||||
|
#ifndef _WIN32
|
||||||
|
util::Log() << "RAM: peak bytes used: " << PeakRAMUsedInBytes();
|
||||||
#else // _WIN32
|
#else // _WIN32
|
||||||
util::Log() << "RAM: peak bytes used: <not implemented on Windows>";
|
util::Log() << "RAM: peak bytes used: <not implemented on Windows>";
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
}
|
}
|
||||||
} // namespace osrm::util
|
} // namespace osrm::util
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
Generated
+12
-1
@@ -10,7 +10,8 @@
|
|||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "BSD-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@mapbox/node-pre-gyp": "^1.0.11"
|
"@mapbox/node-pre-gyp": "^1.0.11",
|
||||||
|
"seedrandom": "^3.0.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/cli": "^7.18.10",
|
"@babel/cli": "^7.18.10",
|
||||||
@@ -14652,6 +14653,11 @@
|
|||||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
||||||
"devOptional": true
|
"devOptional": true
|
||||||
},
|
},
|
||||||
|
"node_modules/seedrandom": {
|
||||||
|
"version": "3.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz",
|
||||||
|
"integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg=="
|
||||||
|
},
|
||||||
"node_modules/semver": {
|
"node_modules/semver": {
|
||||||
"version": "5.7.2",
|
"version": "5.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
|
||||||
@@ -30296,6 +30302,11 @@
|
|||||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
||||||
"devOptional": true
|
"devOptional": true
|
||||||
},
|
},
|
||||||
|
"seedrandom": {
|
||||||
|
"version": "3.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz",
|
||||||
|
"integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg=="
|
||||||
|
},
|
||||||
"semver": {
|
"semver": {
|
||||||
"version": "5.7.2",
|
"version": "5.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
|
||||||
|
|||||||
+7
-4
@@ -4,7 +4,8 @@
|
|||||||
"private": false,
|
"private": false,
|
||||||
"description": "The Open Source Routing Machine is a high performance routing engine written in C++ designed to run on OpenStreetMap data.",
|
"description": "The Open Source Routing Machine is a high performance routing engine written in C++ designed to run on OpenStreetMap data.",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@mapbox/node-pre-gyp": "^1.0.11"
|
"@mapbox/node-pre-gyp": "^1.0.11",
|
||||||
|
"seedrandom": "^3.0.5"
|
||||||
},
|
},
|
||||||
"browserify": {
|
"browserify": {
|
||||||
"transform": [
|
"transform": [
|
||||||
@@ -57,6 +58,7 @@
|
|||||||
"jsonpath": "^1.1.1",
|
"jsonpath": "^1.1.1",
|
||||||
"mkdirp": "^0.5.6",
|
"mkdirp": "^0.5.6",
|
||||||
"node-addon-api": "^5.0.0",
|
"node-addon-api": "^5.0.0",
|
||||||
|
"node-cmake": "^2.5.1",
|
||||||
"node-timeout": "0.0.4",
|
"node-timeout": "0.0.4",
|
||||||
"polyline": "^0.2.0",
|
"polyline": "^0.2.0",
|
||||||
"request": "^2.88.2",
|
"request": "^2.88.2",
|
||||||
@@ -64,12 +66,13 @@
|
|||||||
"tape": "^4.16.0",
|
"tape": "^4.16.0",
|
||||||
"turf": "^3.0.14",
|
"turf": "^3.0.14",
|
||||||
"uglify-js": "^3.17.0",
|
"uglify-js": "^3.17.0",
|
||||||
"xmlbuilder": "^4.2.1",
|
"xmlbuilder": "^4.2.1"
|
||||||
"node-cmake": "^2.5.1"
|
|
||||||
},
|
},
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"binary": {
|
"binary": {
|
||||||
"napi_versions": [8],
|
"napi_versions": [
|
||||||
|
8
|
||||||
|
],
|
||||||
"module_name": "node_osrm",
|
"module_name": "node_osrm",
|
||||||
"module_path": "./lib/binding_napi_v{napi_build_version}/",
|
"module_path": "./lib/binding_napi_v{napi_build_version}/",
|
||||||
"host": "https://github.com",
|
"host": "https://github.com",
|
||||||
|
|||||||
@@ -90,6 +90,7 @@ function setup()
|
|||||||
path = walking_speed,
|
path = walking_speed,
|
||||||
steps = walking_speed,
|
steps = walking_speed,
|
||||||
pedestrian = walking_speed,
|
pedestrian = walking_speed,
|
||||||
|
platform = walking_speed,
|
||||||
footway = walking_speed,
|
footway = walking_speed,
|
||||||
pier = walking_speed,
|
pier = walking_speed,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -0,0 +1,211 @@
|
|||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
const readline = require('readline');
|
||||||
|
const seedrandom = require('seedrandom');
|
||||||
|
|
||||||
|
|
||||||
|
let RNG;
|
||||||
|
|
||||||
|
class GPSData {
|
||||||
|
constructor(gpsTracesFilePath) {
|
||||||
|
this.tracks = {};
|
||||||
|
this.coordinates = [];
|
||||||
|
this.trackIds = [];
|
||||||
|
this._loadGPSTraces(gpsTracesFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
_loadGPSTraces(gpsTracesFilePath) {
|
||||||
|
const expandedPath = path.resolve(gpsTracesFilePath);
|
||||||
|
const data = fs.readFileSync(expandedPath, 'utf-8');
|
||||||
|
const lines = data.split('\n');
|
||||||
|
const headers = lines[0].split(',');
|
||||||
|
|
||||||
|
const latitudeIndex = headers.indexOf('Latitude');
|
||||||
|
const longitudeIndex = headers.indexOf('Longitude');
|
||||||
|
const trackIdIndex = headers.indexOf('TrackID');
|
||||||
|
|
||||||
|
for (let i = 1; i < lines.length; i++) {
|
||||||
|
if (lines[i].trim() === '') continue;
|
||||||
|
const row = lines[i].split(',');
|
||||||
|
|
||||||
|
const latitude = parseFloat(row[latitudeIndex]);
|
||||||
|
const longitude = parseFloat(row[longitudeIndex]);
|
||||||
|
const trackId = row[trackIdIndex];
|
||||||
|
|
||||||
|
const coord = [longitude, latitude];
|
||||||
|
this.coordinates.push(coord);
|
||||||
|
|
||||||
|
if (!this.tracks[trackId]) {
|
||||||
|
this.tracks[trackId] = [];
|
||||||
|
}
|
||||||
|
this.tracks[trackId].push(coord);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.trackIds = Object.keys(this.tracks);
|
||||||
|
}
|
||||||
|
|
||||||
|
getRandomCoordinate() {
|
||||||
|
const randomIndex = Math.floor(RNG() * this.coordinates.length);
|
||||||
|
return this.coordinates[randomIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
getRandomTrack() {
|
||||||
|
const randomIndex = Math.floor(RNG() * this.trackIds.length);
|
||||||
|
const trackId = this.trackIds[randomIndex];
|
||||||
|
return this.tracks[trackId];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
async function runOSRMMethod(osrm, method, coordinates) {
|
||||||
|
const time = await new Promise((resolve, reject) => {
|
||||||
|
const startTime = process.hrtime();
|
||||||
|
osrm[method]({coordinates}, (err, result) => {
|
||||||
|
if (err) {
|
||||||
|
if (['NoSegment', 'NoMatch', 'NoRoute', 'NoTrips'].includes(err.message)) {
|
||||||
|
resolve(null);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
reject(err);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const endTime = process.hrtime(startTime);
|
||||||
|
resolve(endTime[0] + endTime[1] / 1e9);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function nearest(osrm, gpsData) {
|
||||||
|
const times = [];
|
||||||
|
for (let i = 0; i < 1000; i++) {
|
||||||
|
const coord = gpsData.getRandomCoordinate();
|
||||||
|
times.push(await runOSRMMethod(osrm, 'nearest', [coord]));
|
||||||
|
}
|
||||||
|
return times;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function route(osrm, gpsData) {
|
||||||
|
const times = [];
|
||||||
|
for (let i = 0; i < 1000; i++) {
|
||||||
|
const from = gpsData.getRandomCoordinate();
|
||||||
|
const to = gpsData.getRandomCoordinate();
|
||||||
|
|
||||||
|
|
||||||
|
times.push(await runOSRMMethod(osrm, 'route', [from, to]));
|
||||||
|
}
|
||||||
|
return times;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function table(osrm, gpsData) {
|
||||||
|
const times = [];
|
||||||
|
for (let i = 0; i < 250; i++) {
|
||||||
|
const numPoints = Math.floor(RNG() * 3) + 15;
|
||||||
|
const coordinates = [];
|
||||||
|
for (let i = 0; i < numPoints; i++) {
|
||||||
|
coordinates.push(gpsData.getRandomCoordinate());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
times.push(await runOSRMMethod(osrm, 'table', coordinates));
|
||||||
|
}
|
||||||
|
return times;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function match(osrm, gpsData) {
|
||||||
|
const times = [];
|
||||||
|
for (let i = 0; i < 1000; i++) {
|
||||||
|
const numPoints = Math.floor(RNG() * 50) + 50;
|
||||||
|
const coordinates = gpsData.getRandomTrack().slice(0, numPoints);
|
||||||
|
|
||||||
|
|
||||||
|
times.push(await runOSRMMethod(osrm, 'match', coordinates));
|
||||||
|
}
|
||||||
|
return times;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function trip(osrm, gpsData) {
|
||||||
|
const times = [];
|
||||||
|
for (let i = 0; i < 250; i++) {
|
||||||
|
const numPoints = Math.floor(RNG() * 2) + 5;
|
||||||
|
const coordinates = [];
|
||||||
|
for (let i = 0; i < numPoints; i++) {
|
||||||
|
coordinates.push(gpsData.getRandomCoordinate());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
times.push(await runOSRMMethod(osrm, 'trip', coordinates));
|
||||||
|
}
|
||||||
|
return times;
|
||||||
|
}
|
||||||
|
|
||||||
|
function bootstrapConfidenceInterval(data, numSamples = 1000, confidenceLevel = 0.95) {
|
||||||
|
let means = [];
|
||||||
|
let dataLength = data.length;
|
||||||
|
|
||||||
|
for (let i = 0; i < numSamples; i++) {
|
||||||
|
let sample = [];
|
||||||
|
for (let j = 0; j < dataLength; j++) {
|
||||||
|
let randomIndex = Math.floor(RNG() * dataLength);
|
||||||
|
sample.push(data[randomIndex]);
|
||||||
|
}
|
||||||
|
let sampleMean = sample.reduce((a, b) => a + b, 0) / sample.length;
|
||||||
|
means.push(sampleMean);
|
||||||
|
}
|
||||||
|
|
||||||
|
means.sort((a, b) => a - b);
|
||||||
|
let lowerBoundIndex = Math.floor((1 - confidenceLevel) / 2 * numSamples);
|
||||||
|
let upperBoundIndex = Math.floor((1 + confidenceLevel) / 2 * numSamples);
|
||||||
|
let mean = means.reduce((a, b) => a + b, 0) / means.length;
|
||||||
|
let lowerBound = means[lowerBoundIndex];
|
||||||
|
let upperBound = means[upperBoundIndex];
|
||||||
|
|
||||||
|
return { mean: mean, lowerBound: lowerBound, upperBound: upperBound };
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculateConfidenceInterval(data) {
|
||||||
|
let { mean, lowerBound, upperBound } = bootstrapConfidenceInterval(data);
|
||||||
|
let bestValue = Math.max(...data);
|
||||||
|
let errorMargin = (upperBound - lowerBound) / 2;
|
||||||
|
|
||||||
|
return { mean, errorMargin, bestValue };
|
||||||
|
}
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const args = process.argv.slice(2);
|
||||||
|
|
||||||
|
const {OSRM} = require(args[0]);
|
||||||
|
const path = args[1];
|
||||||
|
const algorithm = args[2].toUpperCase();
|
||||||
|
const method = args[3];
|
||||||
|
const gpsTracesFilePath = args[4];
|
||||||
|
const iterations = parseInt(args[5]);
|
||||||
|
|
||||||
|
const gpsData = new GPSData(gpsTracesFilePath);
|
||||||
|
const osrm = new OSRM({path, algorithm});
|
||||||
|
|
||||||
|
|
||||||
|
const functions = {
|
||||||
|
route: route,
|
||||||
|
table: table,
|
||||||
|
nearest: nearest,
|
||||||
|
match: match,
|
||||||
|
trip: trip
|
||||||
|
};
|
||||||
|
const func = functions[method];
|
||||||
|
if (!func) {
|
||||||
|
throw new Error('Unknown method');
|
||||||
|
}
|
||||||
|
const allTimes = [];
|
||||||
|
for (let i = 0; i < iterations; i++) {
|
||||||
|
RNG = seedrandom(42);
|
||||||
|
allTimes.push((await func(osrm, gpsData)).filter(t => t !== null));
|
||||||
|
}
|
||||||
|
|
||||||
|
const opsPerSec = allTimes.map(times => times.length / times.reduce((a, b) => a + b, 0));
|
||||||
|
const { mean, errorMargin, bestValue } = calculateConfidenceInterval(opsPerSec);
|
||||||
|
console.log(`Ops: ${mean.toFixed(1)} ± ${errorMargin.toFixed(1)} ops/s. Best: ${bestValue.toFixed(1)} ops/s`);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
main();
|
||||||
@@ -53,6 +53,7 @@ function run_benchmarks_for_folder {
|
|||||||
mkdir -p $RESULTS_FOLDER
|
mkdir -p $RESULTS_FOLDER
|
||||||
|
|
||||||
BENCHMARKS_FOLDER="$BINARIES_FOLDER/src/benchmarks"
|
BENCHMARKS_FOLDER="$BINARIES_FOLDER/src/benchmarks"
|
||||||
|
|
||||||
echo "Running match-bench MLD"
|
echo "Running match-bench MLD"
|
||||||
$BENCHMARKS_FOLDER/match-bench "$FOLDER/test/data/mld/monaco.osrm" mld > "$RESULTS_FOLDER/match_mld.bench"
|
$BENCHMARKS_FOLDER/match-bench "$FOLDER/test/data/mld/monaco.osrm" mld > "$RESULTS_FOLDER/match_mld.bench"
|
||||||
echo "Running match-bench CH"
|
echo "Running match-bench CH"
|
||||||
@@ -81,6 +82,18 @@ function run_benchmarks_for_folder {
|
|||||||
echo "Running osrm-contract"
|
echo "Running osrm-contract"
|
||||||
measure_peak_ram_and_time "$BINARIES_FOLDER/osrm-contract $FOLDER/data.osrm" "$RESULTS_FOLDER/osrm_contract.bench"
|
measure_peak_ram_and_time "$BINARIES_FOLDER/osrm-contract $FOLDER/data.osrm" "$RESULTS_FOLDER/osrm_contract.bench"
|
||||||
|
|
||||||
|
|
||||||
|
for ALGORITHM in ch mld; do
|
||||||
|
for BENCH in nearest table trip route match; do
|
||||||
|
echo "Running node $BENCH $ALGORITHM"
|
||||||
|
START=$(date +%s.%N)
|
||||||
|
node $SCRIPTS_FOLDER/scripts/ci/bench.js $FOLDER/lib/binding/node_osrm.node $FOLDER/data.osrm $ALGORITHM $BENCH $GPS_TRACES > "$RESULTS_FOLDER/node_${BENCH}_${ALGORITHM}.bench" 5
|
||||||
|
END=$(date +%s.%N)
|
||||||
|
DIFF=$(echo "$END - $START" | bc)
|
||||||
|
echo "Took: ${DIFF}s"
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
for ALGORITHM in ch mld; do
|
for ALGORITHM in ch mld; do
|
||||||
for BENCH in nearest table trip route match; do
|
for BENCH in nearest table trip route match; do
|
||||||
echo "Running random $BENCH $ALGORITHM"
|
echo "Running random $BENCH $ALGORITHM"
|
||||||
|
|||||||
@@ -16,8 +16,8 @@
|
|||||||
#include "osrm/osrm.hpp"
|
#include "osrm/osrm.hpp"
|
||||||
#include "osrm/status.hpp"
|
#include "osrm/status.hpp"
|
||||||
|
|
||||||
|
#include "util/meminfo.hpp"
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
|
|
||||||
#include <boost/optional/optional.hpp>
|
#include <boost/optional/optional.hpp>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
@@ -655,6 +655,12 @@ try
|
|||||||
std::cerr << "Unknown benchmark: " << benchmarkToRun << std::endl;
|
std::cerr << "Unknown benchmark: " << benchmarkToRun << std::endl;
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::cout << "Peak RAM: " << std::setprecision(3)
|
||||||
|
<< static_cast<double>(osrm::util::PeakRAMUsedInBytes()) /
|
||||||
|
static_cast<double>((1024 * 1024))
|
||||||
|
<< "MB" << std::endl;
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
catch (const std::exception &e)
|
catch (const std::exception &e)
|
||||||
|
|||||||
Reference in New Issue
Block a user