首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >有什么建议,如果可能的话,如何使这个脚本更快?

有什么建议,如果可能的话,如何使这个脚本更快?
EN

Code Review用户
提问于 2023-04-19 19:12:01
回答 1查看 66关注 0票数 0

我编写了一个脚本,它使用上传的excel文件将数据导入数据库。它首先检查图像是否可以下载,没有任何错误,然后插入其余的数据。有一万或十万行,这需要几个小时。有可能以某种方式使它更快吗?

代码语言:javascript
复制
= 400 && $http_code < 600 || $ssl === 1) {
            return false;
        }

        try {
            $stream = stream_context_create (array("ssl" => array("capture_peer_cert" => true)));
            if(!empty($url)){
                $read = @fopen($url, "rb", false, $stream);
            
            if ($read !== false) {
                $cont = @stream_context_get_params($read);
                $ssl = ($cont["options"]["ssl"]);
                fclose($read);
        
                return (isset($ssl['peer_certificate']) && !is_null($ssl['peer_certificate'])) ? true : false;
            } else {
                return false;
            }
        }
        }catch(ErrorException $e){
            error_log($e->getMessage());
            return false;
        }
    }


    public function import($path)
    {
        $tempDirectoryName = 'temp';
        $data = Excel::toArray([], $path);
        $dataChunks = array_chunk($data[0], 25);
        foreach ($dataChunks as $chunk) {
            DB::beginTransaction();
            foreach ($chunk as $row) {
                if (!empty($row[3])) {
                    $valid = $this->checkURL($row[3]);
                    if ($valid === true) {
                        $video = Videos::with(['categories', 'stars', 'tags'])->where('url', $row[0])->first();
                        if (!$video) {
                            $slug = Str::slug($row[1], '-');
                            $i = 1;
                            while (Videos::where('slug', $slug)->exists()) {
                                $slug = Str::slug($row[1], '-') . '-' . $i;
                                $i++;
                            }
                            
                            $video = Videos::create([
                                'url' => $row[0],
                                'title' => $row[1],
                                'slug' => $slug,
                                'length' => intval($row[2]),
                                'code' => intval($row[7]),
                                'embed_url' => $row[4],
                                'channel' => $row[9]
                            ]);
                        }

                        try {
                            $media = $video->addMediaFromUrl($row[3])->toMediaCollection('video_index_images', 'public');
                        } catch (\Exception $e) {
                            Log::error("Error importing media for video ID {$video->id}: {$e->getMessage()}");
                            continue;
                        }

                        if (!$media && !$media->exists()) {
                            Log::error("Error importing media for video ID {$video->id}: Invalid media file");
                            continue;
                        }

                            $title = str_replace('_', ' ', $row[8]);
                            $slug = strtolower(str_replace(' ', '-', $title));
                            $title = ucfirst(strtolower($title));
                            $category = Categories::firstOrCreate(['title' => $title], ['slug' => $slug]);
                            $video->categories()->syncWithoutDetaching([$category->id]);

                            $names = explode(',', $row[6]);
                            foreach ($names as $name) {
                                $name = trim($name);
                                $name = str_replace('_', '', $name);
                                $slug = strtolower(str_replace(' ', '-', $name));
                                $star = Stars::firstOrCreate(['name' => $name], ['slug' => $slug]);
                                $video->stars()->syncWithoutDetaching([$star->id]);
                            }

                            $tags = explode(',', $row[5]);
                            $tagIds = [];
                            foreach ($tags as $tagName) {
                                $tagName = str_replace('-', ' ', trim($tagName));
                                if (!empty(trim($tagName))) {
                                    $tag = Tags::firstOrCreate(['name' => $tagName, 'slug' => Str::slug($tagName)]);
                                    $tagIds[] = $tag->id;
                                }
                            }

                            $video->tags()->detach();
                            $video->tags()->attach($tagIds);

                            $tempDirectory = storage_path('media-library/temp/'.$tempDirectoryName);
                            if (file_exists($tempDirectory)) {
                                \File::deleteDirectory($tempDirectory);
                            }
                    }
                }
            }
            DB::commit();
        }
    }
} 

我知道代码在循环中做了很多工作,但为了按预期工作,所有这些步骤都是必要的。

excel文件由10列组成:

  1. 视频的url
  2. 视频标题
  3. 以秒为单位
  4. 指向视频索引图像的url
  5. 嵌入码
  6. 标签
  7. 录影带中的演员
  8. 唯一代码
  9. 类别
  10. 视频来源的站点的名称

该网站将是一个视频集合,所以外部媒体文件总是需要在上传时。一些索引图像的url丢失等等,这些视频不会被上传,这就是为什么我首先检查图像,然后才上传其余的。

使用以下操作在filamentphp资源文件中调用该脚本:

代码语言:javascript
复制
->actions([ Tables\Actions\Action::make('Run') 
   ->icon('heroicon-o-play') 
   ->requiresConfirmation() 
   ->form([ FileUpload::make('excel') 
   ->label('Excel')
   ->acceptedFileTypes(['application/vnd.openxmlformatsofficedocument.spreadsheetml.sheet']) 
   ->preserveFilenames(),]) 
   ->action(function ($data) { 
      $path = 'public/' . $data['excel'];
      $importScript = new DataImport();
      $importScript->import($path); 
      Storage::delete($path);
     })
  ])
EN

回答 1

Code Review用户

发布于 2023-04-30 19:42:21

一些简短的评论:

  • 函数checkURL是在循环中调用的,但在该函数中,每次都会关闭连接。相反,您可以通过reusing ( Curl句柄)来加快速度--打开一个新的连接会增加一些开销。另外,SSL协商中也存在开销。背景阅读
  • 这不一定是代码中最大的瓶颈,但是如果您在从同一个远程主机获取数据时经常调用该函数,那么您应该能够显着地减少运行时间。
  • 更好的是,您可以并行地获取多个URL,例如使用卷曲_多点_初始化函数。这需要对代码进行一些重构。您还需要记住,目标网站可能会应用rate限制。太多的连接会使服务器紧张,可能会让你被禁止,所以要温柔点。
  • 但既然你不是在欺骗用户代理,显然你是个机器人
  • 如果您正在获取“一万或十万行”,这总是需要一些时间,特别是当您正在下载的文件有点大的时候。但同样,并行处理也会有所帮助。
  • 这段代码很难在适当的实时环境下进行测试,因此,正如上面所说的,如果您能够对代码的不同部分进行基准测试并找出究竟需要很长时间的话,就会有帮助。
票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/284560

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档