Skip to content

Commit 4b9294e

Browse files
authored
Merge pull request #178 from jonahwilliams/typed_data_optimization
Avoid wrapping List<int>/Stream<List<int>> response bodies in a CastList/CastStream
2 parents df794c6 + e32c5f9 commit 4b9294e

File tree

4 files changed

+48
-2
lines changed

4 files changed

+48
-2
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
## 1.1.1
2+
3+
* Avoid wrapping response bodies that already contained `List<int>` or
4+
`Stream<List<int>>` in a `CastList`/`CastStream` to improve
5+
performance.
6+
17
## 1.1.0
28

39
* Change `Request.hijack` return type from `void` to `Never`. This may cause

lib/src/body.dart

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,16 @@ class Body {
5252
contentLength = encoded.length;
5353
stream = Stream.fromIterable([encoded]);
5454
}
55+
} else if (body is List<int>) {
56+
// Avoid performance overhead from an unnecessary cast.
57+
contentLength = body.length;
58+
stream = Stream.value(body);
5559
} else if (body is List) {
5660
contentLength = body.length;
57-
stream = Stream.fromIterable([body.cast()]);
61+
stream = Stream.value(body.cast());
62+
} else if (body is Stream<List<int>>) {
63+
// Avoid performance overhead from an unnecessary cast.
64+
stream = body;
5865
} else if (body is Stream) {
5966
stream = body.cast();
6067
} else {

pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: shelf
2-
version: 1.1.0
2+
version: 1.1.1
33
description: >-
44
A model for web server middleware that encourages composition and easy reuse
55
repository: https://github.com/dart-lang/shelf

test/response_test.dart

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import 'dart:async';
66
import 'dart:convert';
7+
import 'dart:typed_data';
78

89
import 'package:shelf/shelf.dart' hide Request;
910
import 'package:test/test.dart';
@@ -25,6 +26,38 @@ void main() {
2526
});
2627
});
2728

29+
test('supports a Uint8List body without copying', () async {
30+
var bytes = Uint8List(10);
31+
var response = Response.ok(bytes);
32+
33+
expect(response.contentLength, 10);
34+
expect(await response.read().single, same(bytes));
35+
});
36+
37+
test('supports a List<int> body without copying', () async {
38+
var bytes = <int>[1, 2, 3, 4];
39+
var response = Response.ok(bytes);
40+
41+
expect(response.contentLength, 4);
42+
expect(await response.read().single, same(bytes));
43+
});
44+
45+
test('supports a Stream<List<int>> body without copying', () async {
46+
var bytes = Stream.value(<int>[1, 2, 3, 4]);
47+
var response = Response.ok(bytes);
48+
49+
expect(response.read(), same(bytes));
50+
});
51+
52+
test('Copies a dynamic list of int elements', () async {
53+
var bytes = <dynamic>[1, 2, 3, 4];
54+
var response = Response.ok(bytes);
55+
56+
expect(response.contentLength, 4);
57+
expect(await response.read().single,
58+
isA<List<int>>().having((values) => values, 'values', [1, 2, 3, 4]));
59+
});
60+
2861
group('new Response.internalServerError without a body', () {
2962
test('sets the body to "Internal Server Error"', () {
3063
var response = Response.internalServerError();

0 commit comments

Comments
 (0)