Skip to content

Commit 934c890

Browse files
committed
Performance and Memory improvement for loops
Adds Memory Manager to Environment. This way memory can be reclaimed once the Environment goes out of scope. So everything that only lives in a certain Environment, as variables do, should be allocated via that "allocator".
1 parent f0475ee commit 934c890

File tree

3 files changed

+23
-16
lines changed

3 files changed

+23
-16
lines changed

environment.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
#include <string>
66
#include <iostream>
77

8+
#include "ast_fwd_decl.hpp"
89
#include "ast_def_macros.hpp"
10+
#include "memory_manager.hpp"
911

1012
namespace Sass {
1113
using std::string;
@@ -20,6 +22,7 @@ namespace Sass {
2022
ADD_PROPERTY(Environment*, parent);
2123

2224
public:
25+
Memory_Manager<AST_Node> mem;
2326
Environment() : current_frame_(map<string, T>()), parent_(0) { }
2427

2528
map<string, T>& current_frame() { return current_frame_; }

eval.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,9 @@ namespace Sass {
100100
double start = static_cast<Number*>(low)->value();
101101
double end = static_cast<Number*>(high)->value();
102102
Env new_env;
103-
new_env[variable] = new (ctx.mem) Number(low->pstate(), start);
103+
// only create iterator once in this environment
104+
Number* it = new (new_env.mem) Number(low->pstate(), start);
105+
new_env[variable] = it;
104106
new_env.link(env);
105107
env = &new_env;
106108
Block* body = f->block();
@@ -109,15 +111,15 @@ namespace Sass {
109111
if (f->is_inclusive()) ++end;
110112
for (double i = start;
111113
i < end;
112-
(*env)[variable] = new (ctx.mem) Number(low->pstate(), ++i)) {
114+
it->value(++i)) {
113115
val = body->perform(this);
114116
if (val) break;
115117
}
116118
} else {
117119
if (f->is_inclusive()) --end;
118120
for (double i = start;
119121
i > end;
120-
(*env)[variable] = new (ctx.mem) Number(low->pstate(), --i)) {
122+
it->value(--i)) {
121123
val = body->perform(this);
122124
if (val) break;
123125
}
@@ -132,17 +134,17 @@ namespace Sass {
132134
Expression* expr = e->list()->perform(this);
133135
List* list = 0;
134136
Map* map = 0;
137+
Env new_env;
135138
if (expr->concrete_type() == Expression::MAP) {
136139
map = static_cast<Map*>(expr);
137140
}
138141
else if (expr->concrete_type() != Expression::LIST) {
139-
list = new (ctx.mem) List(expr->pstate(), 1, List::COMMA);
142+
list = new (new_env.mem) List(expr->pstate(), 1, List::COMMA);
140143
*list << expr;
141144
}
142145
else {
143146
list = static_cast<List*>(expr);
144147
}
145-
Env new_env;
146148
for (size_t i = 0, L = variables.size(); i < L; ++i) new_env[variables[i]] = 0;
147149
new_env.link(env);
148150
env = &new_env;
@@ -154,7 +156,7 @@ namespace Sass {
154156
Expression* value = map->at(key);
155157

156158
if (variables.size() == 1) {
157-
List* variable = new (ctx.mem) List(map->pstate(), 2, List::SPACE);
159+
List* variable = new (new_env.mem) List(map->pstate(), 2, List::SPACE);
158160
*variable << key;
159161
*variable << value;
160162
(*env)[variables[0]] = variable;
@@ -171,7 +173,7 @@ namespace Sass {
171173
for (size_t i = 0, L = list->length(); i < L; ++i) {
172174
List* variable = 0;
173175
if ((*list)[i]->concrete_type() != Expression::LIST || variables.size() == 1) {
174-
variable = new (ctx.mem) List((*list)[i]->pstate(), 1, List::COMMA);
176+
variable = new (new_env.mem) List((*list)[i]->pstate(), 1, List::COMMA);
175177
*variable << (*list)[i];
176178
}
177179
else {
@@ -182,7 +184,7 @@ namespace Sass {
182184
(*env)[variables[j]] = (*variable)[j];
183185
}
184186
else {
185-
(*env)[variables[j]] = new (ctx.mem) Null(expr->pstate());
187+
(*env)[variables[j]] = new (new_env.mem) Null(expr->pstate());
186188
}
187189
val = body->perform(this);
188190
if (val) break;

expand.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -297,22 +297,24 @@ namespace Sass {
297297
double start = static_cast<Number*>(low)->value();
298298
double end = static_cast<Number*>(high)->value();
299299
Env new_env;
300-
new_env[variable] = new (ctx.mem) Number(low->pstate(), start);
300+
// only create iterator once in this environment
301+
Number* it = new (new_env.mem) Number(low->pstate(), start);
302+
new_env[variable] = it;
301303
new_env.link(env);
302304
env = &new_env;
303305
Block* body = f->block();
304306
if (start < end) {
305307
if (f->is_inclusive()) ++end;
306308
for (double i = start;
307309
i < end;
308-
(*env)[variable] = new (ctx.mem) Number(low->pstate(), ++i)) {
310+
it->value(++i)) {
309311
append_block(body);
310312
}
311313
} else {
312314
if (f->is_inclusive()) --end;
313315
for (double i = start;
314316
i > end;
315-
(*env)[variable] = new (ctx.mem) Number(low->pstate(), --i)) {
317+
it->value(--i)) {
316318
append_block(body);
317319
}
318320
}
@@ -326,17 +328,17 @@ namespace Sass {
326328
Expression* expr = e->list()->perform(eval->with(env, backtrace));
327329
List* list = 0;
328330
Map* map = 0;
331+
Env new_env;
329332
if (expr->concrete_type() == Expression::MAP) {
330333
map = static_cast<Map*>(expr);
331334
}
332335
else if (expr->concrete_type() != Expression::LIST) {
333-
list = new (ctx.mem) List(expr->pstate(), 1, List::COMMA);
336+
list = new (new_env.mem) List(expr->pstate(), 1, List::COMMA);
334337
*list << expr;
335338
}
336339
else {
337340
list = static_cast<List*>(expr);
338341
}
339-
Env new_env;
340342
for (size_t i = 0, L = variables.size(); i < L; ++i) new_env[variables[i]] = 0;
341343
new_env.link(env);
342344
env = &new_env;
@@ -348,7 +350,7 @@ namespace Sass {
348350
Expression* v = map->at(key)->perform(eval->with(env, backtrace));
349351

350352
if (variables.size() == 1) {
351-
List* variable = new (ctx.mem) List(map->pstate(), 2, List::SPACE);
353+
List* variable = new (new_env.mem) List(map->pstate(), 2, List::SPACE);
352354
*variable << k;
353355
*variable << v;
354356
(*env)[variables[0]] = variable;
@@ -363,7 +365,7 @@ namespace Sass {
363365
for (size_t i = 0, L = list->length(); i < L; ++i) {
364366
List* variable = 0;
365367
if ((*list)[i]->concrete_type() != Expression::LIST || variables.size() == 1) {
366-
variable = new (ctx.mem) List((*list)[i]->pstate(), 1, List::COMMA);
368+
variable = new (new_env.mem) List((*list)[i]->pstate(), 1, List::COMMA);
367369
*variable << (*list)[i];
368370
}
369371
else {
@@ -374,7 +376,7 @@ namespace Sass {
374376
(*env)[variables[j]] = (*variable)[j]->perform(eval->with(env, backtrace));
375377
}
376378
else {
377-
(*env)[variables[j]] = new (ctx.mem) Null(expr->pstate());
379+
(*env)[variables[j]] = new (new_env.mem) Null(expr->pstate());
378380
}
379381
}
380382
append_block(body);

0 commit comments

Comments
 (0)