Skip to content

Commit 6a219e3

Browse files
committed
reuse sequence vectors in State (5-12% speedup)
Results on a 900K LU corpus of -nob: | Command | Old | New | Improvement | |-------------|---------|---------|-------------| | lt-proc -w | 17.33 s | 15.96 s | 7.9% | | | 2210 MB | 1936 MB | 12.4% | | lt-proc -we | 28.77 s | 25.20 s | 12.4% | | | 2220 MB | 2106 MB | 5.1% |
1 parent 4fb8d65 commit 6a219e3

File tree

3 files changed

+47
-17
lines changed

3 files changed

+47
-17
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
22
cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
33
project(lttoolbox
4-
VERSION 3.8.0
4+
VERSION 3.8.1
55
LANGUAGES CXX C
66
)
77
set(VERSION ${PROJECT_VERSION})

lttoolbox/state.cc

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,26 @@ State::destroy()
6060
}
6161

6262
state.clear();
63+
64+
for (auto& it : sequence_pool) {
65+
delete it;
66+
}
67+
sequence_pool.clear();
68+
}
69+
70+
std::vector<std::pair<int, double>>*
71+
State::new_sequence() {
72+
if (sequence_pool.empty()) {
73+
sequence_pool.push_back(new std::vector<std::pair<int, double>>());
74+
}
75+
auto ret = sequence_pool.back();
76+
sequence_pool.pop_back();
77+
return ret;
78+
}
79+
80+
void
81+
State::free_sequence(std::vector<std::pair<int, double>>* seq) {
82+
sequence_pool.push_back(seq);
6383
}
6484

6585
void
@@ -70,12 +90,15 @@ State::copy(State const &s)
7090
{
7191
delete state[i].sequence;
7292
}
93+
for (auto& it : sequence_pool) {
94+
delete it;
95+
}
7396

7497
state = s.state;
7598

7699
for(size_t i = 0, limit = state.size(); i != limit; i++)
77100
{
78-
std::vector<std::pair<int, double>> *tmp = new std::vector<std::pair<int, double>>();
101+
auto tmp = new_sequence();
79102
*tmp = *(state[i].sequence);
80103
state[i].sequence = tmp;
81104
}
@@ -91,7 +114,7 @@ void
91114
State::init(Node *initial)
92115
{
93116
state.clear();
94-
state.push_back(TNodeState(initial, new std::vector<std::pair<int, double>>(), false));
117+
state.push_back(TNodeState(initial, new_sequence(), false));
95118
state[0].sequence->clear();
96119
epsilonClosure();
97120
}
@@ -105,7 +128,7 @@ State::apply_into(std::vector<TNodeState>* new_state, int const input, int index
105128
{
106129
for(int j = 0; j != it->second.size; j++)
107130
{
108-
std::vector<std::pair<int, double>> *new_v = new std::vector<std::pair<int, double>>();
131+
auto new_v = new_sequence();
109132
*new_v = *(state[index].sequence);
110133
if(it->first != 0)
111134
{
@@ -127,7 +150,7 @@ State::apply_into_override(std::vector<TNodeState>* new_state, int const input,
127150
{
128151
for(int j = 0; j != it->second.size; j++)
129152
{
130-
std::vector<std::pair<int, double>> *new_v = new std::vector<std::pair<int, double>>();
153+
auto new_v = new_sequence();
131154
*new_v = *(state[index].sequence);
132155
if(it->first != 0)
133156
{
@@ -160,7 +183,7 @@ State::apply(int const input)
160183
for(size_t i = 0, limit = state.size(); i != limit; i++)
161184
{
162185
apply_into(&new_state, input, i, false);
163-
delete state[i].sequence;
186+
free_sequence(state[i].sequence);
164187
}
165188

166189
state = new_state;
@@ -180,7 +203,7 @@ State::apply_override(int const input, int const old_sym, int const new_sym)
180203
{
181204
apply_into_override(&new_state, input, old_sym, new_sym, i, false);
182205
apply_into_override(&new_state, old_sym, old_sym, new_sym, i, true);
183-
delete state[i].sequence;
206+
free_sequence(state[i].sequence);
184207
}
185208

186209
state = new_state;
@@ -207,7 +230,7 @@ State::apply_override(int const input, int const alt, int const old_sym, int con
207230
apply_into_override(&new_state, input, old_sym, new_sym, i, false);
208231
apply_into_override(&new_state, alt, old_sym, new_sym, i, true);
209232
apply_into_override(&new_state, old_sym, old_sym, new_sym, i, true);
210-
delete state[i].sequence;
233+
free_sequence(state[i].sequence);
211234
}
212235

213236
state = new_state;
@@ -233,7 +256,7 @@ State::apply(int const input, int const alt)
233256
{
234257
apply_into(&new_state, input, i, false);
235258
apply_into(&new_state, alt, i, true);
236-
delete state[i].sequence;
259+
free_sequence(state[i].sequence);
237260
}
238261

239262
state = new_state;
@@ -255,7 +278,7 @@ State::apply_careful(int const input, int const alt)
255278
{
256279
apply_into(&new_state, alt, i, true);
257280
}
258-
delete state[i].sequence;
281+
free_sequence(state[i].sequence);
259282
}
260283

261284
state = new_state;
@@ -271,7 +294,7 @@ State::epsilonClosure()
271294
{
272295
for(int j = 0 ; j != it2->second.size; j++)
273296
{
274-
std::vector<std::pair<int, double>> *tmp = new std::vector<std::pair<int, double>>();
297+
auto tmp = new_sequence();
275298
*tmp = *(state[i].sequence);
276299
if(it2->second.out_tag[j] != 0)
277300
{
@@ -309,7 +332,7 @@ State::apply(int const input, int const alt1, int const alt2)
309332
apply_into(&new_state, input, i, false);
310333
apply_into(&new_state, alt1, i, true);
311334
apply_into(&new_state, alt2, i, true);
312-
delete state[i].sequence;
335+
free_sequence(state[i].sequence);
313336
}
314337

315338
state = new_state;
@@ -342,7 +365,7 @@ State::apply(int const input, std::set<int> const alts)
342365
apply_into(&new_state, *sit, i, true);
343366
}
344367

345-
delete state[i].sequence;
368+
free_sequence(state[i].sequence);
346369
}
347370

348371
state = new_state;
@@ -793,7 +816,7 @@ State::pruneCompounds(int requiredSymbol, int separationSymbol, int compound_max
793816
{
794817
if(noOfCompoundElements[i] > minNoOfCompoundElements)
795818
{
796-
delete (*it).sequence;
819+
free_sequence((*it).sequence);
797820
it = state.erase(it);
798821
}
799822
else
@@ -821,7 +844,7 @@ State::pruneStatesWithForbiddenSymbol(int forbiddenSymbol)
821844
if((seq->at(i)).first == forbiddenSymbol)
822845
{
823846
i=-1;
824-
delete (*it).sequence;
847+
free_sequence((*it).sequence);
825848
it = state.erase(it);
826849
found = true;
827850
}
@@ -895,7 +918,8 @@ State::restartFinals(const std::map<Node *, double> &finals, int requiredSymbol,
895918
for(unsigned int j=0; j<restart_state->state.size(); j++)
896919
{
897920
TNodeState initst = restart_state->state.at(j);
898-
std::vector<std::pair<int, double>> *tnvec = new std::vector<std::pair<int, double>>;
921+
auto tnvec = new_sequence();
922+
tnvec->clear();
899923

900924
for(unsigned int k=0; k < state_i.sequence->size(); k++)
901925
{
@@ -943,7 +967,7 @@ void
943967
State::merge(const State& other)
944968
{
945969
for (auto& it : other.state) {
946-
std::vector<std::pair<int, double>>* tmp = new std::vector<std::pair<int, double>>();
970+
auto tmp = new_sequence();
947971
*tmp = *(it.sequence);
948972
TNodeState ns(it.where, tmp, it.dirty);
949973
this->state.push_back(std::move(ns));

lttoolbox/state.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,12 @@ class State
6868

6969
std::vector<TNodeState> state;
7070

71+
std::vector<std::vector<std::pair<int, double>>*> sequence_pool;
72+
// get or create a sequence vector (may be non-empty)
73+
std::vector<std::pair<int, double>>* new_sequence();
74+
// return a sequence vector to the pool
75+
void free_sequence(std::vector<std::pair<int, double>>*);
76+
7177
/**
7278
* Destroy function
7379
*/

0 commit comments

Comments
 (0)