Flutter Dart Dio Get Request 太慢了
Flutter Dart Dio Get Request is so slow
我在数字海洋中托管 space - 它基本上是数字海洋的 Amazon S3 等价物。我对 dio 的问题是,我正在使用 dio 向 10MB 大小的文件发出获取请求。该请求在我的 phone 上大约需要 9 秒,但在我的浏览器中需要 3 秒。我的自定义后端也有这个问题。使用 dio(使用 dart 的 http 模块)发出的请求似乎非常慢。我需要解决这个问题,因为我需要不时向用户传输 50MB 的数据。为什么 dio 对 GET 请求的响应很慢?
我怀疑这可能是根本原因check here
await Dio().get(
"Remote_Url_I_can_not_share",
onReceiveProgress: (int downloaded, int total) {
listener
.call((downloaded.toDouble() / total.toDouble() * metadataPerc));
},
cancelToken: _cancelToken,
).catchError((err) => throw err);
我对 DigitalOcean Spaces 的体验非常不稳定。在我看来,DO Spaces 还没有准备好投入生产。我在网站上使用他们的 CDN 功能,有时响应时间约为 20 毫秒,但有时会超过 6 秒。这是在 AMS3 数据中心区域。
您能否确认其他 S3/servers 也会发生这种情况?例如 gstatic,或 Amazon CloudFront CDN?
这种波动行为不断发生,这就是我们将所有资产转移到 Amazon S3 + CloudFront 的原因。它提供了更加一致的结果。
您正在测试的 phone 可能使用非常未优化的 traceroute 到 DigitalOcean 数据中心。这就是为什么你应该尝试不同的服务器。
我相信这个原因;底层某处的缓冲区大小限制为 8KB。
我试了一整天来增加它。仍然没有成功。让我分享一下我对缓冲区大小的经验。
假设您正在下载一个 16 MB 的文件。
请考虑远程服务器的速度也比您的下载速度快。 (我的意思是忘记服务器负载等。)
如果缓冲区大小:
128 字节,下载 16mb 文件需要:10.820 秒
1024 字节,下载 16mb 文件需要:6.276 秒
8192 字节,下载 16mb 文件需要:4.776 秒
16384 字节,下载 16mb 文件需要:3.759 秒
32768 字节,下载 16mb 文件需要:2.956 秒
-------- 在此之后,如果我们增加块大小,下载时间也会增加
65536 字节,下载 16mb 文件需要:4.186 秒
131072 字节,下载 16mb 文件需要:5.250 秒
524288 字节,下载 16mb 文件需要:7.460 秒
所以不知何故,如果您可以将缓冲区大小设置为 16k 或 32k 而不是 8k,我相信下载速度会提高。
请随时测试您的结果(我进行了 3 次尝试,并在时间上取了它们的平均值)
package dltest;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
public class DLTest
{
public static void main(String[] args) throws Exception
{
String filePath = "http://hcmaslov.d-real.sci-nnov.ru/public/mp3/Metallica/Metallica%20'...And%20Justice%20For%20All'.mp3";
URL url = new URL(filePath);
URLConnection uc = url.openConnection();
InputStream is = uc.getInputStream();
long start = System.currentTimeMillis();
int downloaded = 0;
int total = uc.getContentLength();
int partialRead = 0;
// byte chunk[] = new byte[128];
// byte chunk[] = new byte[1024];
// byte chunk[] = new byte[4096];
// byte chunk[] = new byte[8192];
byte chunk[] = new byte[16384];
// byte chunk[] = new byte[32768];
// byte chunk[] = new byte[524288];
while ( (partialRead = is.read(chunk)) != -1)
{
// Print If You Like..
}
is.close();
long end = System.currentTimeMillis();
System.out.println("Chunk Size ["+(chunk.length)+"] Time To Complete : "+(end - start));
}
}
我在数字海洋中托管 space - 它基本上是数字海洋的 Amazon S3 等价物。我对 dio 的问题是,我正在使用 dio 向 10MB 大小的文件发出获取请求。该请求在我的 phone 上大约需要 9 秒,但在我的浏览器中需要 3 秒。我的自定义后端也有这个问题。使用 dio(使用 dart 的 http 模块)发出的请求似乎非常慢。我需要解决这个问题,因为我需要不时向用户传输 50MB 的数据。为什么 dio 对 GET 请求的响应很慢?
我怀疑这可能是根本原因check here
await Dio().get(
"Remote_Url_I_can_not_share",
onReceiveProgress: (int downloaded, int total) {
listener
.call((downloaded.toDouble() / total.toDouble() * metadataPerc));
},
cancelToken: _cancelToken,
).catchError((err) => throw err);
我对 DigitalOcean Spaces 的体验非常不稳定。在我看来,DO Spaces 还没有准备好投入生产。我在网站上使用他们的 CDN 功能,有时响应时间约为 20 毫秒,但有时会超过 6 秒。这是在 AMS3 数据中心区域。
您能否确认其他 S3/servers 也会发生这种情况?例如 gstatic,或 Amazon CloudFront CDN?
这种波动行为不断发生,这就是我们将所有资产转移到 Amazon S3 + CloudFront 的原因。它提供了更加一致的结果。
您正在测试的 phone 可能使用非常未优化的 traceroute 到 DigitalOcean 数据中心。这就是为什么你应该尝试不同的服务器。
我相信这个原因;底层某处的缓冲区大小限制为 8KB。
我试了一整天来增加它。仍然没有成功。让我分享一下我对缓冲区大小的经验。
假设您正在下载一个 16 MB 的文件。
请考虑远程服务器的速度也比您的下载速度快。 (我的意思是忘记服务器负载等。)
如果缓冲区大小:
128 字节,下载 16mb 文件需要:10.820 秒
1024 字节,下载 16mb 文件需要:6.276 秒
8192 字节,下载 16mb 文件需要:4.776 秒
16384 字节,下载 16mb 文件需要:3.759 秒
32768 字节,下载 16mb 文件需要:2.956 秒
-------- 在此之后,如果我们增加块大小,下载时间也会增加
65536 字节,下载 16mb 文件需要:4.186 秒
131072 字节,下载 16mb 文件需要:5.250 秒
524288 字节,下载 16mb 文件需要:7.460 秒
所以不知何故,如果您可以将缓冲区大小设置为 16k 或 32k 而不是 8k,我相信下载速度会提高。
请随时测试您的结果(我进行了 3 次尝试,并在时间上取了它们的平均值)
package dltest;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
public class DLTest
{
public static void main(String[] args) throws Exception
{
String filePath = "http://hcmaslov.d-real.sci-nnov.ru/public/mp3/Metallica/Metallica%20'...And%20Justice%20For%20All'.mp3";
URL url = new URL(filePath);
URLConnection uc = url.openConnection();
InputStream is = uc.getInputStream();
long start = System.currentTimeMillis();
int downloaded = 0;
int total = uc.getContentLength();
int partialRead = 0;
// byte chunk[] = new byte[128];
// byte chunk[] = new byte[1024];
// byte chunk[] = new byte[4096];
// byte chunk[] = new byte[8192];
byte chunk[] = new byte[16384];
// byte chunk[] = new byte[32768];
// byte chunk[] = new byte[524288];
while ( (partialRead = is.read(chunk)) != -1)
{
// Print If You Like..
}
is.close();
long end = System.currentTimeMillis();
System.out.println("Chunk Size ["+(chunk.length)+"] Time To Complete : "+(end - start));
}
}