As I worked on #2149207: Can't save node or create derivitive with image field using s3fs destination and #2109545: Image style generation is very slow, I realized that Drupal reads the same image file several times during certain requests, especially when uploading new images and creating derivatives. Many of these reads are done through repeated calls to getimagesize(), which reads in the first few kilobytes of an image to pull its EXIF data.

I'm thinking about whether it would be a worthwhile performance improvement to keep an in-memory cache of all images (up to a certain max size, say 5MB), which get read from S3. That will make repeated reads of the same image during a single request many, many times faster, since they'll be read from RAM rather than re-downloaded from S3.

This may or may not be especially easy to actually implement, though. If it's possible to just keep a reference to an S3fsSeekableCachingEntityBody object, and load that object whenever the same URI is requested, it would be super easy. But I'm not sure if that'll actually work.

Comments

mikeytown2’s picture

coredumperror’s picture

Hmmm, that wouldn't really remedy the problem that this issue references. It would just push the performance lost to a different request.

mikeytown2’s picture

In the D6 version it cached the results of getimagesize(); that was the module's original purpose. We were using a S3 FUSE mount and this helped drop our page load times by over 10x.

Something similar could be done in D7.

coredumperror’s picture

How did it do that? I'd love to be able to cache just the results of getimagesize(). I looked through the code, but there's so much other stuff going on that I couldn't find the place where it actually did the getimagesize() cache.

mikeytown2’s picture

In D6 the vast majority of the calls to getimagesize came from theme_imagecache() & theme_imagefield_image(). imageinfo_cache_theme_registry_alter implements hook_theme_registry_alter in order to modified the theme layer so that imageinfo_cache_theme_imagecache and imageinfo_cache_theme_imagefield_image run in front and cache the data; and then they call the original theme functions.

In D7 this issue was supposed to be fix in core but if you can point to where multiple calls to getimagesize is happening in core we might be able to patch core or work around the issue.

mikeytown2’s picture

Where getimagesize gets used in core:
image_gd_get_info
color_scheme_form_submit

Popular contrib modules that uses it.
https://drupal.org/project/imagemagick - image_imagemagick_get_info
https://drupal.org/project/imce - imce_image_info depending on configuration
https://drupal.org/project/print - theme_print_pdf_tcpdf_header

Plan of attack would be to implement a fake image_toolkit so that calls to image_get_info will try our cache first.

Other modules that use getimagesize according to gotta download them all via grep -l -r -i "getimagesize(" ./

./allmodules/advanced_title/advanced_title.module                           
./allmodules/aloha/caption/caption.module                                   
./allmodules/andromeda_slideshow_full_slider/full-slider.tpl.php            
./allmodules/acidfree/acidfree.module                                       
./allmodules/asset/asset.module                                             
./allmodules/block_icons/block_icons.module                                 
./allmodules/brilliant_gallery/views.inc                                    
./allmodules/brilliant_gallery/functions.inc                                
./allmodules/bueditor/admin/bueditor.admin.inc                              
./allmodules/bueditor/bueditor.inc                                          
./allmodules/caption_filter/caption_filter.module                           
./allmodules/ckeditor_swf/ckeditor_swf.module                               
./allmodules/drconnect/drconnect.admin.inc                                  
./allmodules/exif_custom/exif_custom.module                                 
./allmodules/fast_gallery/fast_gallery.cache.class.php                      
./allmodules/feeds_imagegrabber/feeds_imagegrabber.module                   
./allmodules/field_slideshow/field_slideshow.module                         
./allmodules/fileframework/formats/image/fileframework_image.module         
./allmodules/filter_html_image_secure/filter_html_image_secure.module       
./allmodules/getlocations/getlocations.markerinfo.inc                       
./allmodules/gmap/gmap_markerinfo.inc                                       
./allmodules/gravatar/gravatar.install                                      
./allmodules/himuesgallery/himuesgallery.module                             
./allmodules/imagecache_proportions/imagecache_proportions.module           
./allmodules/imagemagick/imagemagick.module                                 
./allmodules/imagematrix/MagazineLayout.class.php                           
./allmodules/image_autosize/image_autosize.module                           
./allmodules/image_resize_filter/image_resize_filter.module                 
./allmodules/image_target_question/image_target_question.module             
./allmodules/livefeedback/includes/livefeedback.admin.inc                   
./allmodules/media_browser_plus/includes/media_browser_plus.pages.inc       
./allmodules/media_colorbox/README.txt                                      
./allmodules/media_ustream/README.txt                                       
./allmodules/bracket/FPDF/fpdf.php                                          
./allmodules/bracket/FPDF/fpdf_alpha.php                                    
./allmodules/bracket/bracket_image.inc                                      
./allmodules/bracket/bracket_pdf.inc                                        
./allmodules/opensearch/opensearch.module                                   
./allmodules/print/print_pdf/lib_handlers/print_pdf_tcpdf/print_pdf_tcpdf.pages.inc
./allmodules/regbar/regbar.module                                                  
./allmodules/sassy/sassy_compass/functions/image_size.inc                          
./allmodules/sassy/sassy_compass/functions/inline_image.inc                        
./allmodules/scald/modules/providers/scald_flash/scald_flash.module                
./allmodules/school_administration/school_administration.module                    
./allmodules/search_api_attachments/includes/callback_attachments_settings.inc     
./allmodules/search_file_attachments/search_file_attachments.inc                   
./allmodules/seonet/engines/sape.php                                               
./allmodules/service_links/plugins/service_links_sprites.module                    
./allmodules/spritesheets/spritesheets.inc                                         
./allmodules/spritesheets/spritesheets.module                                      
./allmodules/sweaver/sweaver.module                                                
./allmodules/swfembed/swfembed.module                                              
./allmodules/textmate/Support/commands/generated/theme/6/theme_image.6.php         
./allmodules/textmate/Support/commands/overrides/theme/5/theme_image.5.php         
./allmodules/textmate/Support/commands/overrides/theme/6/theme_image.6.php         
./allmodules/texy/texy/texy.min.php                                                
./allmodules/tinybrowser/tinybrowser/edit.php                                      
./allmodules/tinybrowser/tinybrowser/tinybrowser.php                               
./allmodules/tinybrowser/tinybrowser/upload_process.php                            
./allmodules/translate_this/translate_this.admin.inc                               
./allmodules/ubercart/shipping/uc_shipping/uc_shipping.install                     
./allmodules/userpickit_extras/userpickit_minecraft/userpickit_minecraft.module    
./allmodules/weather/weather_theme.inc                                             
./allmodules/wildfire/modules/wildfire_messages/wildfire_messages.template.api.inc 
./allmodules/wildfire/templates/wildfire.theme                                     
./allmodules/wowguild/classes/WoWGuild.class.inc                                   
./allmodules/ywp/yahoo_webplayer.module                                            
./allmodules/zoomify/ZoomifyFileProcessor.php                                      
./allmodules/ad_lightbox/ad_lightbox.module                                        
./allmodules/aef_image/aef_image.module                                            
./allmodules/audio/images/audio_images.module                                      
./allmodules/cck_formatters/filefieldflash/filefieldflash.module                   
./allmodules/color_soc08/color.module                                              
./allmodules/couloir_slideshow/couloir_slideshow.module                            
./allmodules/dbfm/dbfm.module                                                      
./allmodules/diet/diet_ui/diet_ui.module                                           
./allmodules/diet/diet_ui/theme/diet_ui.theme.inc                                  
./allmodules/dragdrop_gallery/ImageResize.php                                      
./allmodules/endless_page/endless_page.module                                      
./allmodules/fckeditor/fckeditor.module                                            
./allmodules/feedapi_imagegrabber/feedapi_imagegrabber.module                      
./allmodules/feedapi_imagegrabber/CHANGELOG.txt                                    
./allmodules/filefield_audio_insert/filefield_audio_insert.module                  
./allmodules/gallerix/gallerix.module                                              
./allmodules/gallerix/gallerix.build.inc                                           
./allmodules/graphstat/phplot.php                                                  
./allmodules/imagecache/imagecache.module                                          
./allmodules/imagecache_defaults/imagecache_defaults.module                        
./allmodules/imagecrop/includes/imagecrop.class.inc                                
./allmodules/imagefield/imagefield.module                                          
./allmodules/imagefield_assist/imagefield_assist.module                            
./allmodules/imagefield_import/imagefield_import.module                            
./allmodules/image_composition/image.inc                                           
./allmodules/image_composition/magazine-layout/magazinelayout.class.php            
./allmodules/imce/inc/imce.page.inc                                                
./allmodules/imceimage/imceimage.module                                            
./allmodules/img_assist/img_assist.module                                          
./allmodules/jcarousel_block/includes/directoryimage.inc                           
./allmodules/jcarousel_block/includes/imagefield.inc                               
./allmodules/jcarousel_block/includes/imceimage.inc                                
./allmodules/mailing_label/ufpdf/fpdf.php                                          
./allmodules/mail_ru/mail_ru_auth/mail_ru_auth.module                              
./allmodules/mapi/mapi.module                                                      
./allmodules/mappingkit/map2pdf/fpdf/fpdf.php                                      
./allmodules/mapstraction/mapstraction_style_map.inc                               
./allmodules/avatar-uploader/lib/Simple-Ajax-Uploader/README.md                    
./allmodules/barracuda/aegir/patches/imagecache-1243258-5.patch                    
./allmodules/commerce_khipu/commerce_khipu.module                                  
./allmodules/dcco/modules/color/color.module                                       
./allmodules/dcco/modules/system/image.gd.inc                                      
./allmodules/dtn/modules/dtn_weather/dtn_weather.module                            
./allmodules/dummyimage/dummyimage.module                                          
./allmodules/erpal_core/erpal_document_export/plugins/document_export/document_odt_export.inc
./allmodules/erpal_core/erpal_document_export/plugins/document_export/document_ooxml_export.inc
./allmodules/fileviewer/theme/bookreader-viewer.tpl.php                                        
./allmodules/gmap_image_field/gmap_image_field.field.inc                                       
./allmodules/gmap_image_field/gmap_image_field.module                                          
./allmodules/iek/iek.module                                                                    
./allmodules/image_factory/includes/lib/draw_multi_text.inc                                    
./allmodules/image_factory/includes/lib/image_resize.inc
./allmodules/image_factory/includes/save/image_save.inc
./allmodules/imgfly/imgfly.module
./allmodules/mediabox/mediabox.module
./allmodules/media_image_flotsam/providers/custom_url.inc
./allmodules/media_livestream/README.txt
./allmodules/merci_barcode_labels/merci_barcode_labels-ufpdf.php
./allmodules/nitf_views/nitf_views.views.inc
./allmodules/noderef_image_helper/views_plugin_row_noderef_image.inc
./allmodules/node_images/node_images.module
./allmodules/octopus/aegir/patches/imagecache-1243258-5.patch
./allmodules/olowm/lib/openweathermap/OWM.OpenLayers.1.3.4.js
./allmodules/openwysiwyg/openwysiwyg.module
./allmodules/phpbbforum/phpbbforum.sync.inc
./allmodules/qrs_sheets/materials/lib/fpdf/fpdf.php
./allmodules/ReadingRoom/readingroom_viewer_js/readingroom_viewer_js.module
./allmodules/shoutem_api/include/shoutem_api.posts.inc
./allmodules/shoutem_api/include/shoutem_sanitizer.inc
./allmodules/signwriter/signwriter.module
./allmodules/simplecdn/plugins/simplecdn_image/simplecdn_image.module
./allmodules/slideshow_framework/slideshow_framework.module
./allmodules/sprite/sprite.module
./allmodules/ssh_helper/vendor/pdepend/pdepend/src/test/php/PHP/Depend/Log/Jdepend/ChartTest.php
./allmodules/tb_rss_feed/tb_rss_feed.inc
./allmodules/thumb/thumb.module
./allmodules/timthumb/timthumb.php
./allmodules/upload_element/upload_element.module
./allmodules/user_deco/user_deco.modify.inc
./allmodules/user_files/user_files.module
./allmodules/visual_search/visual_search_api.module
./allmodules/webfm/webfm.module
./allmodules/wfs/js/OpenLayers.js
./allmodules/xc/syndetics/syndetics.module
./allmodules/xmedia/xmedia.db.inc
./allmodules/zina/zina/extras/getid3/getid3.lib.php
./allmodules/zina/zina/index.php
./allthemes/ninesixtyfive/phamlp/sass/extensions/compass/functions/imageSize.php
./allthemes/tb_sirate/js/tb_sirate.js
./allthemes/zircon/js/responsive.js
coredumperror’s picture

IIRC, it was image_gd_get_info() which was calling getimagesize() multiple times on the same image, during image upload and derivative creation requests. It's been a while since I last looked into it, though.

mikeytown2’s picture

Implementing our own image_toolkit shouldn't be too hard. We would modify the global $conf variable in hook_init except on the toolkit admin page.

Other contrib modules implementing hook_image_toolkits

./allmodules/imageapi_optimize/imageapi_optimize.module
./allmodules/imagemagick/imagemagick.module
./allmodules/xtools/xtools.xtools.inc
./allmodules/imageapi/imageapi_imagemagick.module

So manual testing wouldn't be that hard to do.

coredumperror’s picture

I don't currently have time to work on s3fs, since I'm busy with other high-priority tasks at work right now. If you want to take a crack at implementing this, I would certainly appreciate it!

mikeytown2’s picture

Project: S3 File System » Imageinfo Cache
Version: 7.x-1.x-dev » 7.x-3.x-dev
Assigned: coredumperror » Unassigned
Category: Task » Feature request

Moving this issue over to imageinfo_cache. Seeing how pantheon has some custom magic going on in here in order to cache the data, I can see how a generalized option will be useful in D7.

mikeytown2’s picture

Assigned: Unassigned » mikeytown2

Will be working on this tomorrow

mikeytown2’s picture

Assigned: mikeytown2 » Unassigned
Status: Active » Fixed
StatusFileSize
new13.06 KB

  • Commit 34e4bc3 on 7.x-3.x by mikeytown2:
    Issue #2153991 by mikeytown2: Add in the ability to cache the...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.