mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Avoid using memmove() for performance; fix #4130
This commit is contained in:
@@ -386,6 +386,7 @@ str_tr(mrb_state *mrb, mrb_value str, mrb_value p1, mrb_value p2, mrb_bool squee
|
|||||||
char *s;
|
char *s;
|
||||||
mrb_int len;
|
mrb_int len;
|
||||||
mrb_int i;
|
mrb_int i;
|
||||||
|
mrb_int j;
|
||||||
mrb_bool flag_changed = FALSE;
|
mrb_bool flag_changed = FALSE;
|
||||||
mrb_int lastch = -1;
|
mrb_int lastch = -1;
|
||||||
|
|
||||||
@@ -395,21 +396,22 @@ str_tr(mrb_state *mrb, mrb_value str, mrb_value p1, mrb_value p2, mrb_bool squee
|
|||||||
s = RSTRING_PTR(str);
|
s = RSTRING_PTR(str);
|
||||||
len = RSTRING_LEN(str);
|
len = RSTRING_LEN(str);
|
||||||
|
|
||||||
for (i = 0; i < len; i++) {
|
for (i=j=0; i<len; i++,j++) {
|
||||||
mrb_int n = tr_find_character(pat, s[i]);
|
mrb_int n = tr_find_character(pat, s[i]);
|
||||||
|
|
||||||
|
if (i>j) s[j] = s[i];
|
||||||
if (n >= 0) {
|
if (n >= 0) {
|
||||||
flag_changed = TRUE;
|
flag_changed = TRUE;
|
||||||
if (rep == NULL) {
|
if (rep == NULL) {
|
||||||
compact:
|
j--;
|
||||||
memmove(s + i, s + i + 1, len - i);
|
|
||||||
len--;
|
|
||||||
i--;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
mrb_int c = tr_get_character(rep, n);
|
mrb_int c = tr_get_character(rep, n);
|
||||||
|
|
||||||
if (squeeze && c == lastch) goto compact;
|
if (squeeze && c == lastch) {
|
||||||
|
j--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (c < 0 || c > 0x80) {
|
if (c < 0 || c > 0x80) {
|
||||||
mrb_raisef(mrb, E_ARGUMENT_ERROR, "character (%S) out of range",
|
mrb_raisef(mrb, E_ARGUMENT_ERROR, "character (%S) out of range",
|
||||||
mrb_fixnum_value((mrb_int)c));
|
mrb_fixnum_value((mrb_int)c));
|
||||||
@@ -422,9 +424,10 @@ str_tr(mrb_state *mrb, mrb_value str, mrb_value p1, mrb_value p2, mrb_bool squee
|
|||||||
tr_free_pattern(mrb, pat);
|
tr_free_pattern(mrb, pat);
|
||||||
if (rep) tr_free_pattern(mrb, rep);
|
if (rep) tr_free_pattern(mrb, rep);
|
||||||
|
|
||||||
RSTR_SET_LEN(RSTRING(str), len);
|
if (flag_changed) {
|
||||||
RSTRING_PTR(str)[len] = 0;
|
RSTR_SET_LEN(RSTRING(str), j);
|
||||||
|
RSTRING_PTR(str)[j] = 0;
|
||||||
|
}
|
||||||
return flag_changed;
|
return flag_changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -542,7 +545,7 @@ static mrb_bool
|
|||||||
str_squeeze(mrb_state *mrb, mrb_value str, mrb_value v_pat)
|
str_squeeze(mrb_state *mrb, mrb_value str, mrb_value v_pat)
|
||||||
{
|
{
|
||||||
struct tr_pattern *pat = NULL;
|
struct tr_pattern *pat = NULL;
|
||||||
mrb_int i;
|
mrb_int i, j;
|
||||||
unsigned char *s;
|
unsigned char *s;
|
||||||
mrb_int len;
|
mrb_int len;
|
||||||
mrb_bool flag_changed = FALSE;
|
mrb_bool flag_changed = FALSE;
|
||||||
@@ -556,34 +559,33 @@ str_squeeze(mrb_state *mrb, mrb_value str, mrb_value v_pat)
|
|||||||
len = RSTRING_LEN(str);
|
len = RSTRING_LEN(str);
|
||||||
|
|
||||||
if (pat) {
|
if (pat) {
|
||||||
for (i = 0; i < len; i++) {
|
for (i=j=0; i<len; i++,j++) {
|
||||||
mrb_int n = tr_find_character(pat, s[i]);
|
mrb_int n = tr_find_character(pat, s[i]);
|
||||||
|
|
||||||
|
if (i>j) s[j] = s[i];
|
||||||
if (n >= 0 && s[i] == lastch) {
|
if (n >= 0 && s[i] == lastch) {
|
||||||
flag_changed = TRUE;
|
flag_changed = TRUE;
|
||||||
memmove(s + i, s + i + 1, len - i);
|
j--;
|
||||||
len--;
|
|
||||||
i--;
|
|
||||||
}
|
}
|
||||||
lastch = s[i];
|
lastch = s[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for (i = 0; i < len; i++) {
|
for (i=j=0; i<len; i++,j++) {
|
||||||
|
if (i>j) s[j] = s[i];
|
||||||
if (s[i] == lastch) {
|
if (s[i] == lastch) {
|
||||||
flag_changed = TRUE;
|
flag_changed = TRUE;
|
||||||
memmove(s + i, s + i + 1, len - i);
|
j--;
|
||||||
len--;
|
|
||||||
i--;
|
|
||||||
}
|
}
|
||||||
lastch = s[i];
|
lastch = s[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tr_free_pattern(mrb, pat);
|
tr_free_pattern(mrb, pat);
|
||||||
|
|
||||||
RSTR_SET_LEN(RSTRING(str), len);
|
if (flag_changed) {
|
||||||
RSTRING_PTR(str)[len] = 0;
|
RSTR_SET_LEN(RSTRING(str), j);
|
||||||
|
RSTRING_PTR(str)[j] = 0;
|
||||||
|
}
|
||||||
return flag_changed;
|
return flag_changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -636,7 +638,7 @@ static mrb_bool
|
|||||||
str_delete(mrb_state *mrb, mrb_value str, mrb_value v_pat)
|
str_delete(mrb_state *mrb, mrb_value str, mrb_value v_pat)
|
||||||
{
|
{
|
||||||
struct tr_pattern *pat = NULL;
|
struct tr_pattern *pat = NULL;
|
||||||
mrb_int i;
|
mrb_int i, j;
|
||||||
char *s;
|
char *s;
|
||||||
mrb_int len;
|
mrb_int len;
|
||||||
mrb_bool flag_changed = FALSE;
|
mrb_bool flag_changed = FALSE;
|
||||||
@@ -646,21 +648,20 @@ str_delete(mrb_state *mrb, mrb_value str, mrb_value v_pat)
|
|||||||
s = RSTRING_PTR(str);
|
s = RSTRING_PTR(str);
|
||||||
len = RSTRING_LEN(str);
|
len = RSTRING_LEN(str);
|
||||||
|
|
||||||
for (i = 0; i < len; i++) {
|
for (i=j=0; i<len; i++,j++) {
|
||||||
mrb_int n = tr_find_character(pat, s[i]);
|
mrb_int n = tr_find_character(pat, s[i]);
|
||||||
|
|
||||||
|
if (i>j) s[j] = s[i];
|
||||||
if (n >= 0) {
|
if (n >= 0) {
|
||||||
flag_changed = TRUE;
|
flag_changed = TRUE;
|
||||||
memmove(s + i, s + i + 1, len - i);
|
j--;
|
||||||
len--;
|
|
||||||
i--;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tr_free_pattern(mrb, pat);
|
tr_free_pattern(mrb, pat);
|
||||||
|
if (flag_changed) {
|
||||||
RSTR_SET_LEN(RSTRING(str), len);
|
RSTR_SET_LEN(RSTRING(str), j);
|
||||||
RSTRING_PTR(str)[len] = 0;
|
RSTRING_PTR(str)[j] = 0;
|
||||||
|
}
|
||||||
return flag_changed;
|
return flag_changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user