- March 22, 2020
- Published.
Kanshi Tanaike
Introduction
V8 engine got to be able to be used at Google Apps Script. By this, I have reported about the process costs with and without using V8. Ref It is considered that knowing the process costs for various methods will be useful for creating the applications with Google Apps Script. Here, I would like to introduce the process costs of each situations under V8. The situations which measured the cost are as follows.
- With and without Arrow function
- “includes” and “indexOf”
- With and without Destructuring Assignment
- With and without Map object
- “Array.prototype.push.apply”, Spread syntax and “concat”
- only “reduce”, “Object.assign” and Spread syntax
- “Array.from”, only “map” and “Object.entries”
Experimental procedure
In this report, the following 2 dimensional array was used for the sample value. 1 dimensional array including 3 strings for searching was used as a source array. The 3 string values were put to the top, center and end of the array in order to measure the same condition. In this case, it uses all of elements in the array. The script for creating this sample array can be seen at here.
By the way, at GAS, the processing time is not stable as you know. So the average value for more than 250 times measurements was used for each data point which is shown by figures. At this time, the fluctuation of the average values was less than 1 %. I worry that each detailed-data point at my environment might be different from that at other user’s environment. But I think that the trend of this result can be used.
Results and discussions
1. With and without Arrow function
The sample script is as follows. The sample script retrieves the rows which include searchText
. In this measurement, the array (ar
) of 3,000,000 rows and 10 columns was used.
const withArrowFunction = ar =>
ar.filter(row => row.some(col => col === searchText));
const withoutArrowFunction = ar =>
ar.filter(function(row) {
return row.some(function(col) {
return col === searchText;
});
});
The result is as follows.
From the result, it was found that the process cost with and without the arrow function was almost the same.
2. “includes” and “indexOf”
The sample script is as follows. The sample script retrieves the rows which include searchText
. In this measurement, the array (ar
) of 3,000,000 rows and 10 columns was used.
const withIncludes = ar => ar.filter(row => row.includes(searchText));
const withIndexOf = ar => ar.filter(row => row.indexOf(searchText) > -1);
The result is as follows.
From the result, it was found that the process cost “includes” and “indexOf” was almost the same.
3. With and without Destructuring Assignment
The sample script is as follows. The sample script retrieves the rows when the values of columns “A”, “E” and “J” are searchText
. In this measurement, the array (ar
) of 3,000,000 rows and 10 columns was used.
const withDestructuringAssignment = ar =>
ar.filter(
([a, , , , e, , , , , j]) =>
a === searchText || e === searchText || j === searchText
);
const withoutDestructuringAssignment = ar =>
ar.filter(
row =>
row[0] === searchText || row[4] === searchText || row[9] === searchText
);
The result is as follows.
From the result, it was found that when the destructuring assignment is used, the cost was about 15 % higher than that without the destructuring assignment.
4. With and without Map object
The sample script is as follows. The sample script removes the duplicated rows. In this measurement, the array (ar
) of 3,000,000 rows and 10 columns was used.
const withMap = ar =>
Object.fromEntries(
ar.reduce((m, [a, , , , e, , , , , j]) => {
if (a === searchText || e === searchText || j === searchText)
m.set(searchText, m.has(searchText) ? m.get(searchText) + 1 : 1);
return m;
}, new Map())
);
const withoutMap = ar =>
ar.reduce((o, [a, , , , e, , , , , j]) => {
if (a === searchText || e === searchText || j === searchText)
o[searchText] = searchText in o ? o[searchText] + 1 : 1;
return o;
}, {});
The result is as follows.
From the result, it was found that the process cost with and without Map object was almost the same. But in this case, the cost of Object.fromEntries
is added. It was found that when Object.fromEntries
is not used, the cost with Map object was about 20 % lower than that without Map object.
5. “Array.prototype.push.apply”, Spread syntax and “concat”
The sample script is as follows. The sample script merges all rows. The costs of Array.prototype.push.apply
, Spread syntax and concat
were measured. In this measurement, the array (ar
) of 3,000 rows and 10 columns was used.
const arrayPrototypePushApply = ar =>
ar.reduce((a, row) => {
Array.prototype.push.apply(a, row);
return a;
}, []);
const spreadSyntax = ar => ar.reduce((a, row) => [...a, row], []);
const concat = ar => ar.reduce((a, row) => a.concat(row), []);
The result is as follows.
From the result, it was found that the process cost of Array.prototype.push
was the lowest of 3 methods. The costs of Spread syntax and concat
were about 3,040 % and 36,666 % higher than that of Array.prototype.push
, respectively.
IMPORTANT POINT
When Array.prototype.push.apply
is used, there is an important point. Please check “Limitation of Array.prototype.push.apply under V8 for Google Apps Script”.
6. only “reduce”, “Object.assign” and Spread syntax
The sample script is as follows. The sample script converts array to JSON object by removing duplicating. The costs of only reduce, Object.assign
and the spread syntax were measured. In this measurement, the array (ar
) of 3,000 rows and 10 columns was used.
const withoutSpreadSyntax = ar =>
ar.reduce((o, row) => {
if (row[0] != searchText) o[row[0]] = row;
return o;
}, {});
const withObjectAssign = ar =>
ar.reduce((o, row) => {
if (row[0] != searchText) return Object.assign(o, { [row[0]]: row });
return o;
}, {});
const withSpreadSyntax = ar =>
ar.reduce((o, row) => {
if (row[0] != searchText) return { ...o, [row[0]]: row };
return o;
}, {});
The result is as follows.
From the result, it was found that the process cost of only reduce
without the spread syntax and Object.assign
was the lowest of 3 methods. The costs of Object.assign
and Spread syntax were about 265 % and 448,063 % higher than that of only reduce
, respectively.
7. “Array.from”, only “map” and “Object.entries”
The sample script is as follows. The sample script converts JSON object to array. The costs of Array.from
, only map and Object.entries
were measured. In this measurement, the array (ar
) of 300,000 rows and 10 columns was used.
const withArrayFrom = obj => Array.from(Object.keys(obj), e => [e, obj[e]]);
const withoutObjectEntries = obj => Object.keys(obj).map(e => [e, obj[e]]);
const withObjectEntries = obj => Object.entries(obj);
The result is as follows.
From the result, it was found that the process costs of Array.from
and only map were almost the same. The cost of Object.entries
was about 131 % higher than that of Array.from
.
Summary
In this report, the process costs of 7 situations under V8 were measured. As the result, the following results could be obtained.
- Process cost with and without the arrow function was almost the same.
- Process cost “includes” and “indexOf” was almost the same.
- When the destructuring assignment is used, the cost was about 15 % higher than that without the destructuring assignment.
- Process cost with and without Map object was almost the same.
- But in this case, the cost of
Object.fromEntries
is added for retrieving the result as the object. And whenObject.fromEntries
is not used, the cost with Map object was about 20 % lower than that without Map object.
- But in this case, the cost of
- Process cost of
Array.prototype.push
was the lowest ofArray.prototype.push.apply
, Spread syntax andconcat
. The costs of Spread syntax andconcat
were about 3,040 % and 36,666 % higher than that ofArray.prototype.push
, respectively. - Process cost of only
reduce
was the lowest of onlyreduce
,Object.assign
and Spread syntax. The costs ofObject.assign
and Spread syntax were about 265 % and 448,063 % higher than that of onlyreduce
, respectively. - Process costs of
Array.from
and only map were almost the same. The cost ofObject.entries
was about 131 % higher than that ofArray.from
.
Note
- As a note, I have to describe that this is the result for Google Apps Script. For other languages, this result might be difference. And also, the process cost of this report might be modified by future update of Google.
- I think that there are various situations except for above situations. So I would like to measure more situations in the future.