热门标签 | HotTags
当前位置:  开发笔记 > 前端 > 正文

DelphiTParallel.for比经典慢

如何解决《DelphiTParallel.for比经典慢》经验,为你挑选了1个好方法。

我需要填充TJsonArray很多TJsonObjectTJsonArray并且TJsonObject来自JsonDataObjects)。我正在尝试TParallel.For()从本System.Threading机提高性能,但是我TParallel.For()的速度比经典for循环慢。

这是我的测试代码:

var
  aLock:  TCriticalSection;
  jItems: TJsonArray;
  jItem:  TJsonObject;
  aStart: Cardinal;
  aEnd:   Cardinal;
  i:      integer;
begin
  // array of json objects
  jItems  := TJsonArray.Create;

  // ASYNC FOR LOOP
  // ----------------------------
  aLock  := TCriticalSection.Create;
  aStart := GetTickCount;
  TParallel.&For(0, 10000000,
    procedure(k: Integer)
    var
      xItem: TJsonObject;
    begin
      aLock.Enter;
      try
        // add new object to the array
        xItem := jItems.AddObject;
      finally
        aLock.Leave;
      end;
      // populate some object property for test
      xItem.I['I'] := k; // .I for integer
      xItem.F['F'] := k; // .F for float
      xItem.S['S'] := IntToStr(k); // .S for string
      xItem.D['D'] := Now; // .D for date
    end
  );
  aEnd := GetTickCount;
  Writeln('ASYNC ', aEnd-aStart);
  // ----------------------------

  aLock.Free;
  jItems.Clear;

  // SYNC FOR LOOP
  // ----------------------------
  aStart := GetTickCount;
  for i := 0 to 10000000 do begin
    jItem := jItems.AddObject;
    jItem.I['I'] := i;
    jItem.F['F'] := i;
    jItem.S['S'] := IntToStr(i);
    jItem.D['D'] := Now;
  end;
  aEnd := GetTickCount;
  Writeln('SYNC ', aEnd-aStart);
  // ----------------------------

  jItems.Free;
end;

这是结果(数字是经过的时间(以毫秒为单位)):

我认为我的TParallel.For()实现是错误的。我究竟做错了什么?



1> Remy Lebeau..:

正如其他人提到的那样,您在TJsonArray序列化周围使用关键部分会使线程线程化,并且可能是主要的瓶颈。尝试摆脱关键部分,在进入循环之前预先分配阵列,然后让每次循环迭代都根据需要简单地填充阵列的现有插槽。这样,您就更有机会同时并行地将多个对象插入到阵列中。

var
  jItems: TJsonArray;
  jItem:  TJsonObject;
  aStart: Cardinal;
  aEnd:   Cardinal;
  i:      integer;
begin
  // array of json objects
  jItems  := TJsonArray.Create;

  // ASYNC FOR LOOP
  // ----------------------------
  jItems.Count := 10000001; // <-- add this!
  aStart := GetTickCount;
  TParallel.&For(0, 10000000,
    procedure(k: Integer)
    var
      xItem: TJsonObject;
    begin

      // create new object
      xItem := TJsonObject.Create;

      // populate some object property for test
      xItem.I['I'] := k; // .I for integer
      xItem.F['F'] := k; // .F for float
      xItem.S['S'] := IntToStr(k); // .S for string
      xItem.D['D'] := Now; // .D for date

      // add new object to the array
      jItems.O[k] := xItem;
    end
  );
  aEnd := GetTickCount;
  Writeln('ASYNC ', aEnd-aStart);
  // ----------------------------

  jItems.Clear;

  // SYNC FOR LOOP
  // ----------------------------
  aStart := GetTickCount;
  for i := 0 to 10000000 do begin
    jItem := jItems.AddObject;
    jItem.I['I'] := i;
    jItem.F['F'] := i;
    jItem.S['S'] := IntToStr(i);
    jItem.D['D'] := Now;
  end;
  aEnd := GetTickCount;
  Writeln('SYNC ', aEnd-aStart);
  // ----------------------------

  jItems.Free;
end;


推荐阅读
  • 本文详细介绍了如何在PHP中记录和管理行为日志,包括ThinkPHP框架中的日志记录方法、日志的用途、实现原理以及相关配置。 ... [详细]
  • 2022年2月 微信小程序 app.json 配置详解:启用调试模式
    本文将详细介绍如何在微信小程序的 app.json 文件中启用调试模式(debug),并通过实际案例展示其配置方法和应用场景。 ... [详细]
  • 了解如何在VSCode中通过配置文件自定义调试控制台的名称。 ... [详细]
  • Python 3 Scrapy 框架执行流程详解
    本文详细介绍了如何在 Python 3 环境下安装和使用 Scrapy 框架,包括常用命令和执行流程。Scrapy 是一个强大的 Web 抓取框架,适用于数据挖掘、监控和自动化测试等多种场景。 ... [详细]
  • 本文总结了一些开发中常见的问题及其解决方案,包括特性过滤器的使用、NuGet程序集版本冲突、线程存储、溢出检查、ThreadPool的最大线程数设置、Redis使用中的问题以及Task.Result和Task.GetAwaiter().GetResult()的区别。 ... [详细]
  • 在JavaWeb开发中,文件上传是一个常见的需求。无论是通过表单还是其他方式上传文件,都必须使用POST请求。前端部分通常采用HTML表单来实现文件选择和提交功能。后端则利用Apache Commons FileUpload库来处理上传的文件,该库提供了强大的文件解析和存储能力,能够高效地处理各种文件类型。此外,为了提高系统的安全性和稳定性,还需要对上传文件的大小、格式等进行严格的校验和限制。 ... [详细]
  • MySQL Decimal 类型的最大值解析及其在数据处理中的应用艺术
    在关系型数据库中,表的设计与SQL语句的编写对性能的影响至关重要,甚至可占到90%以上。本文将重点探讨MySQL中Decimal类型的最大值及其在数据处理中的应用技巧,通过实例分析和优化建议,帮助读者深入理解并掌握这一重要知识点。 ... [详细]
  • 本文介绍了如何使用 Node.js 和 Express(4.x 及以上版本)构建高效的文件上传功能。通过引入 `multer` 中间件,可以轻松实现文件上传。首先,需要通过 `npm install multer` 安装该中间件。接着,在 Express 应用中配置 `multer`,以处理多部分表单数据。本文详细讲解了 `multer` 的基本用法和高级配置,帮助开发者快速搭建稳定可靠的文件上传服务。 ... [详细]
  • 未定义的打字稿记录:探索其成因与解决方案 ... [详细]
  • 技术分享:使用 Flask、AngularJS 和 Jinja2 构建高效前后端交互系统
    技术分享:使用 Flask、AngularJS 和 Jinja2 构建高效前后端交互系统 ... [详细]
  • 您的数据库配置是否安全?DBSAT工具助您一臂之力!
    本文探讨了Oracle提供的免费工具DBSAT,该工具能够有效协助用户检测和优化数据库配置的安全性。通过全面的分析和报告,DBSAT帮助用户识别潜在的安全漏洞,并提供针对性的改进建议,确保数据库系统的稳定性和安全性。 ... [详细]
  • 【实例简介】本文详细介绍了如何在PHP中实现微信支付的退款功能,并提供了订单创建类的完整代码及调用示例。在配置过程中,需确保正确设置相关参数,特别是证书路径应根据项目实际情况进行调整。为了保证系统的安全性,存放证书的目录需要设置为可读权限。值得注意的是,普通支付操作无需证书,但在执行退款操作时必须提供证书。此外,本文还对常见的错误处理和调试技巧进行了说明,帮助开发者快速定位和解决问题。 ... [详细]
  • 本文探讨了在PHP中实现MySQL分页查询功能的优化方法与实际应用。通过详细分析分页查询的常见问题,提出了多种优化策略,包括使用索引、减少查询字段、合理设置缓存等。文章还提供了一个具体的示例,展示了如何通过优化模型加载和分页参数设置,显著提升查询性能和用户体验。 ... [详细]
  • Composer 无法加载本地第三方库?如何解决这一常见问题 ... [详细]
  • 基于Net Core 3.0与Web API的前后端分离开发:Vue.js在前端的应用
    本文介绍了如何使用Net Core 3.0和Web API进行前后端分离开发,并重点探讨了Vue.js在前端的应用。后端采用MySQL数据库和EF Core框架进行数据操作,开发环境为Windows 10和Visual Studio 2019,MySQL服务器版本为8.0.16。文章详细描述了API项目的创建过程、启动步骤以及必要的插件安装,为开发者提供了一套完整的开发指南。 ... [详细]
author-avatar
手机用户2602901497
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有