热门标签 | 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;


推荐阅读
  • golang常用库:配置文件解析库/管理工具viper使用
    golang常用库:配置文件解析库管理工具-viper使用-一、viper简介viper配置管理解析库,是由大神SteveFrancia开发,他在google领导着golang的 ... [详细]
  • 在macOS环境下使用Electron Builder进行应用打包时遇到签名验证失败的问题,具体表现为签名后spctl命令检测到应用程序未通过公证(Notarization)。本文将详细探讨该问题的原因及解决方案。 ... [详细]
  • 前言--页数多了以后需要指定到某一页(只做了功能,样式没有细调)html ... [详细]
  • 本文总结了在使用Ionic 5进行Android平台APK打包时遇到的问题,特别是针对QRScanner插件的改造。通过详细分析和提供具体的解决方法,帮助开发者顺利打包并优化应用性能。 ... [详细]
  • 本文探讨了在 PHP 中处理 JSON 编码时中文字符显示为 Unicode 转义序列的问题,并提供了多种有效的解决方法,包括使用正则表达式替换、URL 编码以及利用 PHP 5.4 及以上版本提供的 JSON_UNESCAPED_UNICODE 选项。 ... [详细]
  • 本文探讨了如何在编程中正确处理包含空数组的 JSON 对象,提供了详细的代码示例和解决方案。 ... [详细]
  • 本文介绍如何使用阿里云的fastjson库解析包含时间戳、IP地址和参数等信息的JSON格式文本,并进行数据处理和保存。 ... [详细]
  • 本文详细介绍了中央电视台电影频道的节目预告,并通过专业工具分析了其加载方式,确保用户能够获取最准确的电视节目信息。 ... [详细]
  • Composer Registry Manager:PHP的源切换管理工具
    本文介绍了一个用于Composer的源切换管理工具——Composer Registry Manager。该项目旨在简化Composer包源的管理和切换,避免与常见的CRM系统混淆,并提供了详细的安装和使用指南。 ... [详细]
  • 本文详细介绍了Git分布式版本控制系统中远程仓库的概念和操作方法。通过具体案例,帮助读者更好地理解和掌握如何高效管理代码库。 ... [详细]
  • 最近团队在部署DLP,作为一个技术人员对于黑盒看不到的地方还是充满了好奇心。多次咨询乙方人员DLP的算法原理是什么,他们都以商业秘密为由避而不谈,不得已只能自己查资料学习,于是有了下面的浅见。身为甲方,虽然不需要开发DLP产品,但是也有必要弄明白DLP基本的原理。俗话说工欲善其事必先利其器,只有在懂这个工具的原理之后才能更加灵活地使用这个工具,即使出现意外情况也能快速排错,越接近底层,越接近真相。根据DLP的实际用途,本文将DLP检测分为2部分,泄露关键字检测和近似重复文档检测。 ... [详细]
  • 本文介绍了如何利用npm脚本和concurrently工具,实现本地开发环境中多个监听服务的同时启动,包括HTTP服务、自动刷新、Sass和ES6支持。 ... [详细]
  • 本文探讨了在通过 API 端点调用时,使用猫鼬(Mongoose)的 findOne 方法总是返回 null 的问题,并提供了详细的解决方案和建议。 ... [详细]
  • 本文详细介绍如何在VSCode中配置自定义代码片段,使其具备与IDEA相似的代码生成快捷键功能。通过具体的Java和HTML代码片段示例,展示配置步骤及效果。 ... [详细]
  • 在网页开发中,页面加载速度是一个关键的用户体验因素。为了提升加载效率,避免在PageLoad事件中进行大量数据绑定操作,可以采用异步加载和特定控件来优化页面加载过程。 ... [详细]
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社区 版权所有