Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[wip] Duktape optimization #1958

Open
wants to merge 49 commits into
base: scene-refactor-base
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
10a41c8
Add Platform::shutdown() to stop workers before going to delete Map
hjanetzek Nov 16, 2018
08aaee8
Linux: don't let http requests block reading local files
hjanetzek Nov 17, 2018
28a44b3
Android: load files asynchronously
hjanetzek Nov 15, 2018
e90b3cd
Android JNI: call from less threads
hjanetzek Dec 6, 2018
869b27c
drop logging
hjanetzek Dec 6, 2018
1c59e1d
Use WeakGlobalRef for android MapController instance
hjanetzek Nov 19, 2018
880c052
Time logger functions
hjanetzek Nov 21, 2018
4daf31c
Timing from scene load to complete view
hjanetzek Nov 21, 2018
5e36b4c
Merge branch 'platform-work' into scene-refactor-base
hjanetzek Dec 7, 2018
3c2d3d5
Merge branch 'time-logging' into scene-refactor-base
hjanetzek Dec 7, 2018
81619ac
Safety check that TextStyle::Param::font exists
hjanetzek Dec 7, 2018
2c20765
linux cmake: glvnd
hjanetzek Dec 7, 2018
82f650c
fixup Textstyle
hjanetzek Dec 8, 2018
25c5684
Merge branch 'small-fixes-and-cleanups' into scene-refactor-base
hjanetzek Dec 8, 2018
22230b0
JS engine templatification
hjanetzek Nov 22, 2018
7ef75bd
Add note to optimize StyleContext
hjanetzek Nov 26, 2018
83daaf4
Testing: pass StyleContext to TileBuilder
hjanetzek Nov 25, 2018
57573af
Benchmark both engines
hjanetzek Nov 25, 2018
4b9587c
Duktape optimizations pt1
hjanetzek Nov 25, 2018
66d27c0
wip: duktape rewrite functions to pass context as arguments
hjanetzek Nov 26, 2018
49df944
wip: test&bench
hjanetzek Nov 27, 2018
56f35c6
wip: faster Filter key matching
hjanetzek Nov 27, 2018
60bf620
wip save
hjanetzek Nov 27, 2018
afdbe68
wip: duktape config
hjanetzek Nov 27, 2018
8ca97e3
Duktape: extstr
hjanetzek Nov 27, 2018
fcb0051
cleanups
hjanetzek Nov 27, 2018
ccd9ad0
Duktape extern string wip
hjanetzek Nov 27, 2018
8b8e57a
bench+test
hjanetzek Nov 27, 2018
118d8b7
Testing stash vs properties to keep heap refs safe
hjanetzek Nov 27, 2018
a5ba41f
Working extstr cache
hjanetzek Nov 30, 2018
5c9e6fc
Use StringCache for different lengths
hjanetzek Dec 1, 2018
a0fc7e6
how can 'i' get greater than 'usage'?
hjanetzek Dec 4, 2018
56cb69a
drop
hjanetzek Nov 30, 2018
651874e
Freeze 'global' and feature proxy object
hjanetzek Dec 4, 2018
dd64435
Cleanup BIND_GLOBAL_TO_FUNCTION
hjanetzek Dec 4, 2018
13871d7
Try global stringStash array to hold feature property strings
hjanetzek Dec 4, 2018
f698d6c
clenaups duktape
hjanetzek Dec 4, 2018
03e74ae
wip: StringProxy
hjanetzek Dec 4, 2018
1f61ca8
>>> wip: Filter upgrade
hjanetzek Dec 4, 2018
48310c6
Disabled layers can be dropped!
hjanetzek Dec 4, 2018
45c6732
save
hjanetzek Dec 7, 2018
8a4d840
wip: early filter/drop unused feature properties
hjanetzek Dec 8, 2018
14e2638
fix: MockPlatform fallback font
hjanetzek Dec 8, 2018
18a2422
StyleContextRecorder tweaks
hjanetzek Dec 8, 2018
c4e2703
Fix stringcache
hjanetzek Dec 8, 2018
1f4a238
squash: bench
hjanetzek Dec 8, 2018
c25983a
Small PointStyleBuilder optimization
hjanetzek Dec 10, 2018
a1ffaf1
#ifdef TIME_LOGGING
hjanetzek Dec 10, 2018
31ac99b
Build with system jscore lib
hjanetzek Dec 10, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
189 changes: 113 additions & 76 deletions bench/src/benchStyleContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "mockPlatform.h"
#include "log.h"
#include "data/tileSource.h"
#include "scene/filters.h"
#include "scene/importer.h"
#include "scene/scene.h"
#include "scene/dataLayer.h"
Expand All @@ -19,14 +20,54 @@

#include <functional>

#define NUM_ITERATIONS 0

#if NUM_ITERATIONS
#define ITERATIONS ->Iterations(NUM_ITERATIONS)
#else
#define ITERATIONS
#endif

#define RUN(FIXTURE, NAME) \
BENCHMARK_DEFINE_F(FIXTURE, NAME)(benchmark::State& st) { while (st.KeepRunning()) { run(); } } \
BENCHMARK_REGISTER_F(FIXTURE, NAME); //->Iterations(10000);
BENCHMARK_REGISTER_F(FIXTURE, NAME) ITERATIONS;

using namespace Tangram;

//const char scene_file[] = "bubble-wrap-style.zip";
const char scene_file[] = "res/scene.yaml";
template<class Context>
class GetPropertyFixtureFixture : public benchmark::Fixture {
public:
Context ctx;
Feature feature;
void SetUp(const ::benchmark::State& state) override {
JavaScriptScope<Context> jsScope(ctx);
ctx.setGlobalValue("language", jsScope.newString("en"));
feature.props.set("name:en", "Ozymandias");
feature.props.set("title", "King of Kings");
feature.props.set("number", 17);
ctx.setCurrentFeature(&feature);
ctx.setFunction(0, "function () { return (language && feature['name:' + language]) || title; }");
ctx.setFunction(1, "function () { return feature.order || feature.number; }");
}
__attribute__ ((noinline)) void run() {
StyleParam::Value value;
benchmark::DoNotOptimize(value);
JavaScriptScope<Context> jsScope(ctx);
value = jsScope.getFunctionResult(0).toString();
value = (float)jsScope.getFunctionResult(1).toDouble();
}
};

#ifdef TANGRAM_USE_JSCORE
using JSCoreGetPropertyFixture = GetPropertyFixtureFixture<JSCore::Context>;
RUN(JSCoreGetPropertyFixture, JSCoreGetPropertyBench)
#endif

using DuktapeGetPropertyFixture = GetPropertyFixtureFixture<Duktape::Context>;
RUN(DuktapeGetPropertyFixture, DuktapeGetPropertyBench)

const char scene_file[] = "bubble-wrap-style.zip";
//const char scene_file[] = "res/scene.yaml";
const char tile_file[] = "res/tile.mvt";

std::shared_ptr<Scene> scene;
Expand Down Expand Up @@ -72,95 +113,91 @@ void globalSetup() {
}
}

__attribute__ ((noinline))
void filter(StyleContext& ctx, const SceneLayer& layer, const Feature& feature) {
StyleParam::Value styleValue;
benchmark::DoNotOptimize(styleValue);

if (layer.filter().eval(feature, ctx)) {
for (auto& r : layer.rules()) {
for (auto& sp : r.parameters) {
if (sp.function >= 0) {
//evalCnt++;
ctx.evalStyle(sp.function, sp.key, styleValue);
}
}
}
for (const auto& sublayer : layer.sublayers()) {
filter(ctx, sublayer, feature);
}
}
}

template<class Context>
class JSGetPropertyFixture : public benchmark::Fixture {
public:
Context ctx;
Feature feature;
void applyStyling(StyleContext& ctx) {
for (const auto& datalayer : scene->layers()) {
for (const auto& collection : tileData->layers) {
if (!collection.name.empty()) {
const auto& dlc = datalayer.collections();
bool layerContainsCollection =
std::find(dlc.begin(), dlc.end(), collection.name) != dlc.end();

if (!layerContainsCollection) { continue; }
}

for (const auto& feature : collection.features) {
ctx.setFeature(feature);
filter(ctx, datalayer, feature);
}
}
}
}

template<size_t jsCore>
struct JSTileStyleFnFixture : public benchmark::Fixture {
std::unique_ptr<StyleContext> ctx;
void SetUp(const ::benchmark::State& state) override {
JavaScriptScope<Context> jsScope(ctx);
ctx.setGlobalValue("language", jsScope.newString("en"));
feature.props.set("name:en", "Ozymandias");
feature.props.set("title", "King of Kings");
feature.props.set("number", 17);
ctx.setCurrentFeature(&feature);
ctx.setFunction(0, "function () { return (language && feature['name:' + language]) || title; }");
ctx.setFunction(1, "function () { return feature.order || feature.number; }");
globalSetup();
ctx.reset(new StyleContext(jsCore));
ctx->initScene(*scene);
ctx->setFilterKey(Filter::Key::zoom, 10);
}
__attribute__ ((noinline)) void run() {
StyleParam::Value value;
benchmark::DoNotOptimize(value);
JavaScriptScope<Context> jsScope(ctx);
value = jsScope.getFunctionResult(0).toString();
value = (float)jsScope.getFunctionResult(1).toDouble();
}
applyStyling(*ctx);
}
};

#ifdef TANGRAM_USE_JSCORE
using JSCoreGetPropertyFixture = JSGetPropertyFixture<JSCoreContext>;
RUN(JSCoreGetPropertyFixture, JSCoreGetPropertyBench)
#else
using DuktapeGetPropertyFixture = JSGetPropertyFixture<DuktapeContext>;
RUN(DuktapeGetPropertyFixture, DuktapeGetPropertyBench)
using JSCoreTileStyleFnFixture = JSTileStyleFnFixture<1>;
RUN(JSCoreTileStyleFnFixture, JSCoreTileStyleFnBench)
#endif
using DuktapeTileStyleFnFixture = JSTileStyleFnFixture<0>;
RUN(DuktapeTileStyleFnFixture, DuktapeTileStyleFnBench)

struct JSTileStyleFnFixture : public benchmark::Fixture {
StyleContext ctx;
Feature feature;
uint32_t numFunctions = 0;
uint32_t evalCnt = 0;

template<size_t jsCore>
struct JSTileStyleFnReplayFixture : public benchmark::Fixture {
std::unique_ptr<StyleContext> ctx;
void SetUp(const ::benchmark::State& state) override {
globalSetup();
ctx.initFunctions(*scene);
ctx.setKeywordZoom(10);
}
void TearDown(const ::benchmark::State& state) override {
LOG(">>> %d", evalCnt);
ctx.reset(new StyleContext(jsCore, true));
ctx->initScene(*scene);
ctx->setFilterKey(Filter::Key::zoom, 10);
applyStyling(*ctx);
ctx->impl->recorderLog();
}
__attribute__ ((noinline)) void run() {
StyleParam::Value styleValue;
benchmark::DoNotOptimize(styleValue);

for (const auto& datalayer : scene->layers()) {
for (const auto& collection : tileData->layers) {
if (!collection.name.empty()) {
const auto& dlc = datalayer.collections();
bool layerContainsCollection =
std::find(dlc.begin(), dlc.end(), collection.name) != dlc.end();

if (!layerContainsCollection) { continue; }
}

for (const auto& feat : collection.features) {
ctx.setFeature(feat);

std::function<void(const SceneLayer& layer)> filter;
filter = [&](const auto& layer) {
if (layer.filter().eval(feature, ctx)) {
for (auto& r : layer.rules()) {
for (auto& sp : r.parameters) {
if (sp.function >= 0) {
evalCnt++;
ctx.evalStyle(sp.function, sp.key, styleValue);
}
}
}

for (const auto& sublayer : layer.sublayers()) {
filter(sublayer);
}
}
};
filter(datalayer);
}
}
}
ctx->impl->replayFilters();
ctx->impl->replayStyles();
}
};

RUN(JSTileStyleFnFixture, TileStyleFnBench);
#ifdef TANGRAM_USE_JSCORE
using JSCoreTileStyleFnReplayFixture = JSTileStyleFnReplayFixture<1>;
RUN(JSCoreTileStyleFnReplayFixture, JSCoreTileStyleFnReplayBench)
#endif
using DuktapeTileStyleFnReplayFixture = JSTileStyleFnReplayFixture<0>;
RUN(DuktapeTileStyleFnReplayFixture, DuktapeTileStyleFnReplayBench)


class DirectGetPropertyFixture : public benchmark::Fixture {
public:
Expand All @@ -182,6 +219,6 @@ BENCHMARK_DEFINE_F(DirectGetPropertyFixture, DirectGetPropertyBench)(benchmark::
}
}
}
BENCHMARK_REGISTER_F(DirectGetPropertyFixture, DirectGetPropertyBench);
BENCHMARK_REGISTER_F(DirectGetPropertyFixture, DirectGetPropertyBench) ITERATIONS;

BENCHMARK_MAIN();
32 changes: 24 additions & 8 deletions bench/src/benchTileBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,34 @@
#include <iostream>
#include <vector>

#define NUM_ITERATIONS 0

#if NUM_ITERATIONS
#define ITERATIONS ->Iterations(NUM_ITERATIONS)
#else
#define ITERATIONS
#endif

#define RUN(FIXTURE, NAME) \
BENCHMARK_DEFINE_F(FIXTURE, NAME)(benchmark::State& st) { while (st.KeepRunning()) { run(); } } \
BENCHMARK_REGISTER_F(FIXTURE, NAME); //->Iterations(1)
BENCHMARK_REGISTER_F(FIXTURE, NAME)ITERATIONS;

using namespace Tangram;

//const char scene_file[] = "bubble-wrap-style.zip";
const char scene_file[] = "res/scene.yaml";
const char scene_file[] = "bubble-wrap-style.zip";
//const char scene_file[] = "res/scene.yaml";
const char tile_file[] = "res/tile.mvt";

std::shared_ptr<Scene> scene;
std::shared_ptr<TileSource> source;
std::shared_ptr<TileData> tileData;
std::shared_ptr<MockPlatform> platform;

void globalSetup() {
static std::atomic<bool> initialized{false};
if (initialized.exchange(true)) { return; }
static bool initialized = false;
if (initialized) { return; }

std::shared_ptr<MockPlatform> platform = std::make_shared<MockPlatform>();
platform = std::make_shared<MockPlatform>();

Url sceneUrl(scene_file);
platform->putMockUrlContents(sceneUrl, MockPlatform::getBytesFromFile(scene_file));
Expand Down Expand Up @@ -74,27 +82,35 @@ void globalSetup() {
LOGE("Invalid tile file '%s'", tile_file);
exit(-1);
}
initialized = true;
}

template<size_t jscontext>
class TileBuilderFixture : public benchmark::Fixture {
public:
std::unique_ptr<TileBuilder> tileBuilder;
StyleContext* styleContext;
std::shared_ptr<Tile> result;
void SetUp(const ::benchmark::State& state) override {
globalSetup();
tileBuilder = std::make_unique<TileBuilder>(scene, new StyleContext());
styleContext = new StyleContext(jscontext);
tileBuilder = std::make_unique<TileBuilder>(scene, styleContext);
}
void TearDown(const ::benchmark::State& state) override {
result.reset();
}

__attribute__ ((noinline)) void run() {
result = tileBuilder->build({0,0,10,10}, *tileData, *source);
styleContext->clear();
}
};

RUN(TileBuilderFixture, TileBuilderBench);
using DUKTileBuilderFixture = TileBuilderFixture<0>;
using JSCTileBuilderFixture = TileBuilderFixture<1>;

RUN(DUKTileBuilderFixture, DUKTileBuilderBench)
RUN(JSCTileBuilderFixture, JSCTileBuilderBench)


BENCHMARK_MAIN();
10 changes: 5 additions & 5 deletions core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -138,18 +138,18 @@ target_link_libraries(tangram-core

# Add JavaScript implementation.
if(TANGRAM_JSCORE_ENABLED)
target_sources(tangram-core PRIVATE src/js/JSCoreContext.cpp)
if (TANGRAM_USE_JSCORE_STATIC)
target_link_libraries(tangram-core PRIVATE jscore-static)
# target_link_libraries(tangram-core PRIVATE jscore-static)
pkg_check_modules(JSCORE REQUIRED IMPORTED_TARGET javascriptcoregtk-4.0)
target_link_libraries(tangram-core PRIVATE PkgConfig::JSCORE)
else()
target_link_libraries(tangram-core PRIVATE "-framework JavaScriptCore")
endif()
target_compile_definitions(tangram-core PRIVATE TANGRAM_USE_JSCORE=1)
else()
target_sources(tangram-core PRIVATE src/js/DuktapeContext.cpp)
target_link_libraries(tangram-core PRIVATE duktape)
endif()

target_link_libraries(tangram-core PRIVATE duktape)

# Add MBTiles implementation.
if(TANGRAM_MBTILES_DATASOURCE)
target_sources(tangram-core PRIVATE src/data/mbtilesDataSource.cpp)
Expand Down
6 changes: 4 additions & 2 deletions core/deps/duktape/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
add_library(duktape duktape.c)
add_library(duktape duktape.c extstr.c)

target_compile_options(duktape PRIVATE
-fstrict-aliasing
-fomit-frame-pointer
-std=c99
-Wall)

target_include_directories(duktape PUBLIC .)
target_include_directories(duktape
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR})
Loading