Skip to content

Commit 4ceac47

Browse files
authored
Optimize string repetition and string copying (#2634)
* Faster string repeat algorithm * Optimize `_lfortran_strcpy` * Faster string repeat algorithm * Optimize `_lfortran_strcpy` * Added stress test for repeat
1 parent 8820e02 commit 4ceac47

File tree

2 files changed

+23
-12
lines changed

2 files changed

+23
-12
lines changed

integration_tests/test_str_01.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ def test_str_repeat():
5959
assert a*2*3 == "XyzXyzXyzXyzXyzXyz"
6060
assert 3*a*3 == "XyzXyzXyzXyzXyzXyzXyzXyzXyz"
6161
assert a*-1 == ""
62+
assert len(a*(10**6)) == (3 * 10 ** 6)
6263

6364
def test_str_join():
6465
a: str

src/libasr/runtime/lfortran_intrinsics.c

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1976,12 +1976,14 @@ LFORTRAN_API void _lfortran_strcpy(char** x, char *y, int8_t free_target)
19761976
*x = (char*) malloc((strlen(y) + 1) * sizeof(char));
19771977
_lfortran_string_init(strlen(y) + 1, *x);
19781978
// }
1979-
for (size_t i = 0; i < strlen(*x); i++) {
1980-
if (i < strlen(y)) {
1981-
x[0][i] = y[i];
1982-
} else {
1983-
x[0][i] = ' ';
1984-
}
1979+
size_t y_len = strlen(y);
1980+
size_t x_len = strlen(*x);
1981+
size_t i = 0;
1982+
for (; i < x_len && i < y_len; i++) {
1983+
x[0][i] = y[i];
1984+
}
1985+
for (; i < x_len; i++) {
1986+
x[0][i] = ' ';
19851987
}
19861988
}
19871989

@@ -2129,21 +2131,29 @@ LFORTRAN_API int32_t _lpython_bit_length8(int64_t num)
21292131
//repeat str for n time
21302132
LFORTRAN_API void _lfortran_strrepeat(char** s, int32_t n, char** dest)
21312133
{
2132-
int cntr = 0;
21332134
char trmn = '\0';
21342135
int s_len = strlen(*s);
21352136
int trmn_size = sizeof(trmn);
21362137
int f_len = s_len*n;
21372138
if (f_len < 0)
21382139
f_len = 0;
21392140
char* dest_char = (char*)malloc(f_len+trmn_size);
2140-
for (int i = 0; i < n; i++) {
2141-
for (int j = 0; j < s_len; j++) {
2142-
dest_char[cntr] = (*s)[j];
2143-
cntr++;
2141+
2142+
if (s_len == 1) {
2143+
memset(dest_char, *(*s), n);
2144+
} else {
2145+
memcpy(dest_char, *s, s_len);
2146+
int chars_copied = s_len;
2147+
int copy_length;
2148+
while (chars_copied < f_len) {
2149+
copy_length = (chars_copied <= f_len-chars_copied)
2150+
? chars_copied : f_len-chars_copied;
2151+
memcpy(dest_char+chars_copied, dest_char, copy_length);
2152+
chars_copied += copy_length;
21442153
}
21452154
}
2146-
dest_char[cntr] = trmn;
2155+
2156+
dest_char[f_len] = trmn;
21472157
*dest = &(dest_char[0]);
21482158
}
21492159

0 commit comments

Comments
 (0)