Performance work (#334)

* range encode filter range lists

* speed up data load

* add comment on scanpy read params

* update to latest scanpy/anndata

* performance improvments in data loading

* fix typo

* work around scanpy bug

* remove debugging print statements
This commit is contained in:
Bruce Martin
2018-10-16 15:49:40 -07:00
committed by GitHub
parent 6b0aafd27c
commit 76ec29734a
5 changed files with 142 additions and 11 deletions
+17 -3
View File
@@ -2,8 +2,18 @@
import _ from "lodash";
import * as globals from "../globals";
import { Universe, kvCache } from "../util/stateManager";
import { catchErrorsWrap, doJsonRequest } from "../util/actionHelpers";
import {
catchErrorsWrap,
doJsonRequest,
rangeEncodeIndices
} from "../util/actionHelpers";
/*
Bootstrap application with the initial data loading.
* /config - application configuration
* /schema - schema of dataframe
* /annotations/obs - all metadata annotation
*/
const doInitialDataLoad = () =>
catchErrorsWrap(async dispatch => {
dispatch({ type: "initial data load start" });
@@ -235,8 +245,12 @@ const requestDifferentialExpression = (set1, set2, num_genes = 10) => async (
*/
const state = getState();
const { universe } = state.controls;
const set1ByIndex = _.map(set1, s => universe.obsNameToIndexMap[s]);
const set2ByIndex = _.map(set2, s => universe.obsNameToIndexMap[s]);
const set1ByIndex = rangeEncodeIndices(
_.map(set1, s => universe.obsNameToIndexMap[s])
);
const set2ByIndex = rangeEncodeIndices(
_.map(set2, s => universe.obsNameToIndexMap[s])
);
const diffExpFetch = await fetch(
`${globals.API.prefix}${globals.API.version}diffexp/obs`,
{
+57 -4
View File
@@ -1,3 +1,5 @@
import _ from "lodash";
/*
Catch unexpected errors and make sure we don't lose them!
*/
@@ -11,10 +13,7 @@ export function catchErrorsWrap(fn) {
}
/*
Bootstrap application with the initial data loading.
* /config - application configuration
* /schema - schema of dataframe
* /annotations/obs - all metadata annotation
Wrapper to perform an async fetch and JSON decode response.
*/
export const doJsonRequest = async url => {
const res = await fetch(url, {
@@ -26,3 +25,57 @@ export const doJsonRequest = async url => {
});
return res.json();
};
/*
This function "packs" filter index lists into the more efficient
"range" form specified in the REST 0.2 spec.
Specifically, it turns an array of indices [0, 1, 2, 10, 11, 14, ...]
into a form that encodes runs of consecutive numbers as [min, max].
Array may not be sorted, but will only contain uniq values.
Parameters:
indices - input array of numbers (index)
minRangeLength - hint, min range length before it is encoded into range format.
sorted - boolean hint indicating array is presorted, ascending order
So [1, 2, 3, 4, 10, 11, 14] -> [ [1, 4], [10, 11], 14]
*/
export const rangeEncodeIndices = (
indices,
minRangeLength = 3,
sorted = false
) => {
if (indices.length === 0) {
return indices;
}
if (!sorted) {
indices = _.sortBy(indices);
}
const result = new Array(indices.length);
let resultTail = 0;
let i = 0;
while (i < indices.length) {
const begin = indices[i];
let current;
do {
current = indices[i];
i += 1;
} while (i < indices.length && indices[i] === current + 1);
if (current - begin + 1 >= minRangeLength) {
result[resultTail] = [begin, current];
resultTail += 1;
} else {
for (let j = begin; j <= current; j += 1, resultTail += 1) {
result[resultTail] = j;
}
}
}
result.length = resultTail;
return result;
};