F ROM R ESEARCH T O I NDUSTRY M OBILE EDITION (Or, How I Learned - - PowerPoint PPT Presentation

f rom r esearch t o i ndustry
SMART_READER_LITE
LIVE PREVIEW

F ROM R ESEARCH T O I NDUSTRY M OBILE EDITION (Or, How I Learned - - PowerPoint PPT Presentation

F ROM R ESEARCH T O I NDUSTRY M OBILE EDITION (Or, How I Learned To Stop Worrying about Papers and Start Building Smartphone Apps) Stephen Miller, Co-Founder and SVP Engineering Fyusion, Inc T HIS TALK IS ABOUT How to


slide-1
SLIDE 1

FROM “RESEARCH” TO “INDUSTRY” MOBILE EDITION

(Or, How I Learned To Stop Worrying about Papers and Start Building Smartphone Apps) Stephen Miller, Co-Founder and SVP Engineering Fyusion, Inc

slide-2
SLIDE 2

THIS TALK IS ABOUT…

  • How to future-proof your research code
  • How to transition from academia to industry
  • Hard things I’ve learned growing from a team of ~4 to

a team of >50

  • A few tricks for porting desktop code to mobile
  • Just enough shameless company promotion to justify

reimbursing the flight

slide-3
SLIDE 3

THIS TALK IS NOT ABOUT…

  • In-depth technical details

  • Any particular library

  • Science

  • Computer Vision, really, except insofar as it informs

certain challenges

slide-4
SLIDE 4

YOU ARE…?

slide-5
SLIDE 5

ROUGH OUTLINE

1: Context (~5 min)

  • Who I am
  • What I did before Fyusion
  • What Fyusion is all about

2: Growing pains (~10 min)

  • Problems with going from research -> industry
  • Particular problems with going from desktop ->

mobile

3: Helpful tips (~10 min)

  • General code organization
  • Device-specific vs generic code
  • Broader startup tips (git flow, process, management)
slide-6
SLIDE 6

WHO AM I?

My current face

Robotics 3D Vision Open Source / Industry Collaboration

slide-7
SLIDE 7

https://www.youtube.com/watch?v=5FGVgMsiv1s

ROBOTICS @ BERKELEY

(2007 - 2011)

slide-8
SLIDE 8

GAP BETWEEN ACADEMIC + PUBLIC EXPECTATION

http://abcnews.go.com/Politics/oklahoma-sen-tom-coburn-report-shows-taxpayer-money/story?id=13689403

slide-9
SLIDE 9

3D VISION @ STANFORD

  • Started PhD on 3D perception

  • Use only low-cost ($100 or less)

sensors

Sensor 0 Sensor 1

(2011 - 2014-ish)

slide-10
SLIDE 10
  • World’s largest 3D Image Processing initiative

250 500 3/1/11 9/1/11 3/1/12 9/1/12

CUMULATIVE MONTH TO MONTH

D e v e l

  • p

e r s

MAINTAINER @ PCL

(2011 - present…ish)

slide-11
SLIDE 11

Stop wasting tax dollars and give me all the stuff I saw in the movies

Point clouds, Meshes, Octrees, …

Technologists PROBLEM: CONSUMERS DON’T CARE ABOUT TECH DEMOS Consumers

slide-12
SLIDE 12

Point clouds, Meshes, Octrees, …

Technologists PROBLEM: CONSUMERS DON’T CARE ABOUT TECH DEMOS Consumers

Slick, seamless, “magic”

slide-13
SLIDE 13

THE CHALLENGE: MAKE IT SO STURDY THEY DON’T


KNOW IT’S RESEARCH

slide-14
SLIDE 14

http://fyusion.com

slide-15
SLIDE 15

UNDER THE HOOD: SCIENCE

slide-16
SLIDE 16

TO THE USER: MAGIC

slide-17
SLIDE 17

FASHION, E COMMERCE

slide-18
SLIDE 18

CUSTOM CAPTURE MODES

slide-19
SLIDE 19

EXAMPLE INDUSTRY: AUTOMOTIVE

slide-20
SLIDE 20

EXAMPLE INDUSTRY: AUTOMOTIVE

slide-21
SLIDE 21

HOW DID WE SCALE?

slide-22
SLIDE 22

REQUIRED BUSTING A LOT OF MYTHS

slide-23
SLIDE 23

MYTH: DEMO CODE™

slide-24
SLIDE 24

RECENT EXAMPLE: BOTTLENECK

foreach slice [start, end]: fire up decoder march to start fire up processor process to end

Slices were *nonoverlapping* and 
 *consecutive*.
 This code is extremely wasteful^

slide-25
SLIDE 25

GIT BLAME

slide-26
SLIDE 26

ORIGINAL CODE

fire up decoder process fire up processor

“Just hack it!”

slide-27
SLIDE 27

ORIGINAL CODE

fire up decoder foreach slice [start, end]: march to start fire up processor process to end

“Just hack it!”

Bad code evolves


  • ver time

++

slide-28
SLIDE 28

“JUST HACK IT” - INDUSTRY EDITION

slide-29
SLIDE 29

THE POINT: 


DO IT WELL ENOUGH THE FIRST TIME,
 BECAUSE…

slide-30
SLIDE 30

MYTH: THE ENGINEERS™ WILL DO IT LATER

slide-31
SLIDE 31

“THE ENGINEER” WILL

  • Understand my hacky pseudocode 

  • Convert my O(n^3) algorithm into O(n) with

Optimization™


  • Add helpful comments

  • Rename obscure variables and functions

  • Write unit tests for everything

“The QArchitician is half QA, half Software Architect, half Mathematician!”

slide-32
SLIDE 32

THE ACTUAL ENGINEER WILL

  • Be deeply frustrated to work with brittle

code as a starting point


  • Be very conservative about accidentally

breaking something


  • Require your input and review time, and in

all likelihood…


  • Quarantine your code before they fix it
slide-33
SLIDE 33

AND THEY’LL BE *RIGHT* TO QUARANTINE, BECAUSE…

slide-34
SLIDE 34

TOO MANY COOKS SPOIL THE ALGORITHM

Old, hacky research code % you know offhand: 100

slide-35
SLIDE 35

New, “clean”, “optimized”, “refactored” code % you know offhand: ~60 % they know offhand: ~60 % shared:
 10

TOO MANY COOKS SPOIL THE ALGORITHM

slide-36
SLIDE 36

WHEN CRASHES ATTACK

slide-37
SLIDE 37

WHEN CRASHES ATTACK

“This looks nothing like
 my algorithm.”

slide-38
SLIDE 38

WHEN CRASHES ATTACK

“Don’t ask me, it’s not
 my algorithm.”

slide-39
SLIDE 39

TAKEAWAY: SOMEONE SHOULD FULLY UNDERSTAND


A GIVEN CODE BLOCK.


IF IT’S COMPUTER VISION RELATED, 


THAT SOMEONE IS PROBABLY YOU.

slide-40
SLIDE 40

MYTH: THE PLATFORM IS IRRELEVANT

slide-41
SLIDE 41

There Will Be Bugs

slide-42
SLIDE 42

2016 ANDROID RECORDING BUG

  • Scattered reports from users on a specific device by a European

manufacturer: “Suddenly, the camera just stops sensing motion”

  • Difference in timestamps:


13107153
 13107234
 13107212
 13107128

  • ^ 2^17 second offset
slide-43
SLIDE 43

2017 IPHONE 8 AND X RECORDING BUG

  • “All of a sudden it just stops working” - iPhone 8, 8+, and X users
  • Bonus points for anyone who can tell me what is mathematically interesting

about 768614.395 seconds…

slide-44
SLIDE 44

2015 VIDEO DECODER BUG

  • “It works fine for the first 204…then stops forever”

slide-45
SLIDE 45

2015 VIDEO DECODER BUG

  • Bug in Apple video decoder (lasted at least 3 years)

video200.mp4 video200.mp4 video200.mp4 video204.mp4 Decoder1 Decoder1 Decoder1 Decoder1 Decoder204

slide-46
SLIDE 46

2015 VIDEO DECODER BUG

  • Bug in Apple video decoder (lasted at least 3 years)

video200.mp4 video200.mp4 video200.mp4 video204.mp4 Decoder1 Decoder1 Decoder1 Decoder1 Decoder204 video_sym.mp4

slide-47
SLIDE 47

EXISTENTIAL QUESTION: HOW DO YOU TEST FOR THIS $@*(&?

  • Not scalable to actually test for every possible case


  • Irresponsible not to test for 


every possible case

“Okay, so before a PR can be merged, we need to make sure we run it on this particular model

  • f Alcatel phone for at least 3 weeks, and

also the plus version, and the international version, and a version running Lollipop, and also bring it to that garage, and also…”

slide-48
SLIDE 48

MYTH: I CAN JUST DO IT ON THE CLOUD™ INSTEAD

slide-49
SLIDE 49

GOING TO THE CLOUD

  • 1 minute of 1080p capture on an iPhone = 200MB

  • In many cities, you’ll be lucky if that is done in 5

minutes — and that assumes Apple doesn’t kill you first


  • If you want to scale globally (China, India), you can’t

assume an LTE connection

Strong AI
 Achieved!

Just point at anything
 and our patented
 algorithm will do 
 the rest

slide-50
SLIDE 50

MYTH: I CAN JUST SAVE RAW DATA AND DO IT OFFLINE

slide-51
SLIDE 51

DOING IT OFFLINE

  • 1 minute of 1080p capture = 3600 frames

  • If you have a simple thing (e.g. 10 ms or less), you’re

still looking at 30 seconds to run it

  • And that’s ignoring h264 decoding time!

  • If you can do anything online, do it! Attention spans

are very low, even for cutting edge tech.

slide-52
SLIDE 52

MYTH: IT’LL BE LIKE A LAB, WE CAN WING IT!

slide-53
SLIDE 53

IN THE BEGINNING…

You and a handful of colleagues know every line of code.
 You move extremely quickly, and have no need for QA

  • r code review. 



 
 
 “Meetings” make you think of Dilbert

slide-54
SLIDE 54

EVENTUALLY

50+ people, multiple products, multiple deadlines, actual customers (and this is just one repository) No way for one person to 
 keep track of everything

slide-55
SLIDE 55

REALIZATION: WE NEED A MORE FORMAL PROCESS

slide-56
SLIDE 56

MYTH: PROCESS™ WILL SOLVE IT

slide-57
SLIDE 57

PROCESS: A PRIMER

Step 1: Commit to an insane deadline

Five days? I’ll do it in one!

slide-58
SLIDE 58

PROCESS: A PRIMER

Step 1: Commit to an insane deadline Step 2: Fail

slide-59
SLIDE 59

PROCESS: A PRIMER

Step 1: Commit to an insane deadline Step 2: Fail Step 3: Blame Process™

“We need JIRA!” “Trello or die!” “Did you even read The Lean Startup?!!” “Scrum you fools! It’s been scrum the whole time!”

slide-60
SLIDE 60

THE TRUTH

Process is useful, and necessary.
 
 
 
 
 
 
 
 
 
 
 But it isn’t a magic bullet.

slide-61
SLIDE 61

ENOUGH MYTHS; WHAT SHOULD I DO?

slide-62
SLIDE 62

TIP: BEWARE OF CVPR SYNDROME

  • “What if it also used GANs to predict when the user

wants to stop recording?”


  • “Surely superresolution can help this”

  • “Why are we using JPEG? This latest compression

algorithm is *way* better”


  • “Couldn’t a neural network handle all the 

  • n-screen rendering too?”

  • “This would be much better if I wrapped it


in Haskell”

slide-63
SLIDE 63

TIP: BEWARE OF CVPR SYNDROME

https://www.youtube.com/watch?v=evUWersr7pc

slide-64
SLIDE 64

IT WILL GET MORE COMPLICATED ON ITS OWN.
 DON’T PUSH IT.

  • Customization per customer

  • Exceptions for certain lighting conditions

  • Optimizations for particular phones

  • New battery constraints that force you to fork and

simplify


  • Handling of about 10000 different edge cases

“BUT WAIT, THERE’S…”

slide-65
SLIDE 65

TIP: DON’T REINVENT THE WHEEL

  • Just because you can make it on your own


doesn’t mean you should.
 


  • Many of the things you hate about a certain

codebase are exactly what will happen to

  • yours. But theirs will be tested.

  • Best case scenario: you waste time.
  • Worst case scenario: years of bugfixing

Your hard-coded quaternion arithmetic Eigen::Quaternionf

slide-66
SLIDE 66

TIP: KEEP ALGORITHMS CROSS PLATFORM

libCV.a

Android Source (Java)

FYAndroid.git

CVLib.framework

iOS Source (ObjC, Swift)

FYiOS.git

CVLib Source (C++)

libCV.so

CVLib.git

Debugging Tools Algorithmic Unit Tests

FYServer.git FYOculus.git …

slide-67
SLIDE 67

TIP: I/O IS CRITICAL

State Of The Art ™ “Realtime” Algorithm
 
 25ms

C a m e r a

  • >

g r a y s c a l e c v : : M a t 
 3 m s cv::Mat -> jpeg 
 30ms

  • Always look for hardware accelerated options
  • Minimize unnecessary data


modifications (resizing, color 
 conversions, CPU <-> GPU)

  • Color conversions in particular


are a constant source of bugs;
 settle on a bulletproof 
 convention ASAP

slide-68
SLIDE 68

CVLib.git (C++)

ImageIO.saveImage() RandAccMovieIO.loadFrame(idx) SeqMovieIO.loadNextFrame() DataIO.saveEncrypted(blob) @interface HEIFWriter : ImageIO @interface MJPEGEncoder : RandAccMovieIO @interface HVECEncoder : SyncMovieIO @interface iOSCryptoWrapper : DataIO

FYiOS.git (ObjC)

slide-69
SLIDE 69

CVLib.git (C++)

ImageIO.saveImage() RandAccMovieIO.loadFrame(idx) SeqMovieIO.loadNextFrame() DataIO.saveEncrypted(blob) class JPEGWriter : ImageIO class PNGDirIO : RandAccMovieIO class H264Encoder : SyncMovieIO class FastAndroidEncryptor : DataIO

FYAndroid.git (Java)

slide-70
SLIDE 70

CVLib.git (C++) FYiOS.git (Obj C)

CVImage resize()
 cvtColor()
 toBitmap() toGLBuffer() … iOSImageWrapper MetalTexture UIImage Processor ImageIO IOSProcessingDelegate ProcessingCB() HEIFWriter

slide-71
SLIDE 71

DOWNSIDE: SHARED CODE = TOUGHER QA

slide-72
SLIDE 72

TIP: AUTOMATE EVERYTHING

Grad school edition: Makefiles for everything

slide-73
SLIDE 73

TIP: CONTINUOUS INTEGRATION IS A LIFESAVER

  • Use Jenkins to run sanity checks on device simulators

Build alone is an enormous timesaver, especially on device Keep track of multiple
 products simultaneously

slide-74
SLIDE 74

(PARTICULARLY WITH THE CROSS PLATFORM SIDE)

libCV.a CVLib.framework

CVLib Source (C++)

libCV.so

  • Build all targets (iOS, Android, Desktop) to ensure no API breakage.
  • Alternative: your research engineers will never be able to push code without

having an iPhone, an Android phone, and extraordinary patience

slide-75
SLIDE 75

TIP: (SOME) GIT FLOW IS IMPORTANT

  • Lots of blogs take this to an extreme



 (Feature -> sprint -> epic -> 
 qa -> release -> …)

slide-76
SLIDE 76

TIP: (SOME) GIT FLOW IS IMPORTANT

What works for us is more basic:


  • Engineer makes PR onto dev

  • dev PR gets code review + unit tested 

  • > merged

  • Once all features are in, PR opened from


dev -> release


  • release PR gets more thorough QA, 


manual testing -> merged


  • Only release branch gets shipped to 


iOS, Android, etc repositories

slide-77
SLIDE 77

TIP: FIND THE RIGHT REVIEWING BALANCE

Overly Strict: 


  • Nothing gets merged unless

it is perfect

  • Deadlines slip due to inactivity

/ unwillingness to take any chances

  • Morale drops to 0

Overly Permissive:


  • Everything gets merged

  • Destabilizing crashes ruin

every delivery, deadline rushes create unusable code


  • Morale drops to 0
slide-78
SLIDE 78

6/17/2018 Complex processing changes by sdmiller · Pull Request #1 · sdmiller/cvpr https://github.com/sdmiller/cvpr/pull/1#pullrequestreview-129398515 1/2

master addedProcessing

Trying out slicing 0a85920 Slicing 99472cc 3 days of hard work bbde897 CVPR/Processor.m 46 47 48 49 + + + +‑ (NSArray<ProcessingResult*>*)processForSlices:(NSArray*)slices CVPR/Processor.m 49 50 51 52 +‑ (NSArray<ProcessingResult*>*)processForSlices:(NSArray*)slices +{ + NSMutableArray<ProcessingResult*>* resultsPerSlice = [NSMutableArray new]; + for (Slice* slice in slices) { CVPR/Processor.m 51 52 53 54 + NSMutableArray<ProcessingResult*>* resultsPerSlice = [NSMutableArray new]; + for (Slice* slice in slices) { + ProcessingResult* result = [ProcessingResult new]; + [self.decoder restart]; CVPR/Processor.m 52 53 54 55 + for (Slice* slice in slices) { + ProcessingResult* result = [ProcessingResult new]; + [self.decoder restart]; + int frameCount = ‑1; CVPR/Processor.m 56 57 58 59 + Frame* currentFrame; + while ( (currentFrame = [self.decoder getFrame]) ) { + ++frameCount; + if (frameCount < slice.start) { CVPR/Processor.m 58 59 60 61 + ++frameCount; + if (frameCount < slice.start) { + continue; + } else if (frameCount > slice.end) { CVPR/Processor.m 61 62 63 64 + } else if (frameCount > slice.end) { + break; + } + // BLAH BLAH DO MAGIC CVPR/Processor.m 63 64 65 66 + } + // BLAH BLAH DO MAGIC + } + [resultsPerSlice addObject:result]; CVPR/Processor.m 71 72 73 74 + +‑ (ProcessingResult*)process +{ + ProcessingResult* result = [ProcessingResult new]; CVPR/Processor.m 74 75 76 77 + ProcessingResult* result = [ProcessingResult new]; + [self.decoder restart]; + int frameCount = ‑1; + Frame* currentFrame;

slide-79
SLIDE 79

6/17/2018 Complex processing changes by sdmiller · Pull Request #1 · sdmiller/cvpr https://github.com/sdmiller/cvpr/pull/1#pullrequestreview-129398515 1/2

master addedProcessing

Trying out slicing 0a85920 Slicing 99472cc 3 days of hard work bbde897 CVPR/Processor.m 46 47 48 49 + + + +‑ (NSArray<ProcessingResult*>*)processForSlices:(NSArray*)slices CVPR/Processor.m 49 50 51 52 +‑ (NSArray<ProcessingResult*>*)processForSlices:(NSArray*)slices +{ + NSMutableArray<ProcessingResult*>* resultsPerSlice = [NSMutableArray new]; + for (Slice* slice in slices) { CVPR/Processor.m 51 52 53 54 + NSMutableArray<ProcessingResult*>* resultsPerSlice = [NSMutableArray new]; + for (Slice* slice in slices) { + ProcessingResult* result = [ProcessingResult new]; + [self.decoder restart]; CVPR/Processor.m 52 53 54 55 + for (Slice* slice in slices) { + ProcessingResult* result = [ProcessingResult new]; + [self.decoder restart]; + int frameCount = ‑1; CVPR/Processor.m 56 57 58 59 + Frame* currentFrame; + while ( (currentFrame = [self.decoder getFrame]) ) { + ++frameCount; + if (frameCount < slice.start) { CVPR/Processor.m 58 59 60 61 + ++frameCount; + if (frameCount < slice.start) { + continue; + } else if (frameCount > slice.end) { CVPR/Processor.m 61 62 63 64 + } else if (frameCount > slice.end) { + break; + } + // BLAH BLAH DO MAGIC CVPR/Processor.m 63 64 65 66 + } + // BLAH BLAH DO MAGIC + } + [resultsPerSlice addObject:result]; CVPR/Processor.m 71 72 73 74 + +‑ (ProcessingResult*)process +{ + ProcessingResult* result = [ProcessingResult new]; CVPR/Processor.m 74 75 76 77 + ProcessingResult* result = [ProcessingResult new]; + [self.decoder restart]; + int frameCount = ‑1; + Frame* currentFrame;

slide-80
SLIDE 80

6/17/2018 Complex processing changes by sdmiller · Pull Request #1 · sdmiller/cvpr https://github.com/sdmiller/cvpr/pull/1#pullrequestreview-129398515 1/2

master addedProcessing

Trying out slicing 0a85920 Slicing 99472cc 3 days of hard work bbde897 CVPR/Processor.m 46 47 48 49 + + + +‑ (NSArray<ProcessingResult*>*)processForSlices:(NSArray*)slices CVPR/Processor.m 49 50 51 52 +‑ (NSArray<ProcessingResult*>*)processForSlices:(NSArray*)slices +{ + NSMutableArray<ProcessingResult*>* resultsPerSlice = [NSMutableArray new]; + for (Slice* slice in slices) { CVPR/Processor.m 51 52 53 54 + NSMutableArray<ProcessingResult*>* resultsPerSlice = [NSMutableArray new]; + for (Slice* slice in slices) { + ProcessingResult* result = [ProcessingResult new]; + [self.decoder restart]; CVPR/Processor.m 52 53 54 55 + for (Slice* slice in slices) { + ProcessingResult* result = [ProcessingResult new]; + [self.decoder restart]; + int frameCount = ‑1; CVPR/Processor.m 56 57 58 59 + Frame* currentFrame; + while ( (currentFrame = [self.decoder getFrame]) ) { + ++frameCount; + if (frameCount < slice.start) { CVPR/Processor.m 58 59 60 61 + ++frameCount; + if (frameCount < slice.start) { + continue; + } else if (frameCount > slice.end) { CVPR/Processor.m 61 62 63 64 + } else if (frameCount > slice.end) { + break; + } + // BLAH BLAH DO MAGIC CVPR/Processor.m 63 64 65 66 + } + // BLAH BLAH DO MAGIC + } + [resultsPerSlice addObject:result]; CVPR/Processor.m 71 72 73 74 + +‑ (ProcessingResult*)process +{ + ProcessingResult* result = [ProcessingResult new]; CVPR/Processor.m 74 75 76 77 + ProcessingResult* result = [ProcessingResult new]; + [self.decoder restart]; + int frameCount = ‑1; + Frame* currentFrame;

slide-81
SLIDE 81

HEALTHY EXPECTATIONS IN RELATIONSHIPS

Dan Savage relationship advice: “There's no perfect person, no perfect person for you, no perfect match…etc. You'll meet a 0.64 or two if you're lucky—if you're really lucky you might even meet a 0.72—and it's your job to round that [person] up to one.”

slide-82
SLIDE 82

HEALTHY EXPECTATIONS IN CODE

My engineering sanity advice: No one will write perfect code, with perfect variable names, perfect comment styles, a unit test for every method so thorough we will know it works simply if it runs. Like human relationships, if you want to ever have a chance at merging, round “pretty good!” up to perfect and move on with your life.

slide-83
SLIDE 83

TIP: BUFFERS (THE HUMAN KIND) ARE CRITICAL

Feb 2016: I take over a project for a big client.
 Biweekly phone calls, incremental features. “Hacking is fun! I could do this in my sleep!”
 PRs every day or two with good, targeted improvements By March… ~15 self merge PRs a day, usually with curse words attached.

slide-84
SLIDE 84

BURNOUT

By April… Actual photo in China after 2 sleepless weeks Fever medicine

slide-85
SLIDE 85

HOW IT WORKS: ENGINEER <-> CUSTOMER

“Is X possible?” “How long?” Boss 2: “PUSH PUSH PUSH” “Great talk to you in 16 hours with a new buglist!” “Yes everything is trivial” “I have a PhD 9 hours” “What about Y?” “Idk, 7 hours?” Boss 1: 
 “Keep Customer happy” “I don’t pay you to sleep!” “But what about sleep?” “You don’t pay me at a—“

Engineer Customer’s
 PM

slide-86
SLIDE 86

1 WEEK LATER

Boss 2: “Great pushing today, Jimbo!” Boss 1: “Why is our codebase in Piglatin?”

slide-87
SLIDE 87

HOW IT SHOULD WORK: PM <-> CUSTOMER

Product Manager Customer’s
 PM

“Is X possible?” “How long?” “So when will it be ready?” “I don’t know I’d need to ask my Engineer.” “I’ll ask tomorrow.” “What about Y?” “I’ll ask tomorrow.” Boss 1:
 “Keep Customer happy” “Okay put it in a giant spreadsheet” “Engineers, right? I’ll text u tmrw” “I love those!” Boss 2: “PUSH PUSH PUSH”

slide-88
SLIDE 88

HOW IT SHOULD WORK: PM <-> ENGINEER

Product Manager Engineer

“I went rock climbing and watched Westworld, per CS stereotype” “Are you even listening I have a Ph—” “How was your weekend, champ?” “Cool cool cool hey, can we touch base on X later?” “It’s trivial I have a PhD I could do that in 9 hours.” “Can you do it by Friday?” “Friday! You’re a champ!”

slide-89
SLIDE 89

1 WEEK LATER

Boss 2: “Great pushing today, Jimbo!” Boss 1: “Friday deadline on track?”

slide-90
SLIDE 90

LOW-LEVEL LIGHTNING ROUND

slide-91
SLIDE 91

TIP: GUARD THE MAIN THREAD WITH YOUR LIFE

Viewer

  • Separate viewing logic


(previsualization, computation) from actual
 rendering


  • iOS: DisplayLink very useful here

  • Bonus: manually decode JPEGs on a


background thread; don’t let viewer
 handle it on the fly

slide-92
SLIDE 92

TIP: GUARD THE MAIN THREAD WITH YOUR LIFE

Viewer Camera

  • Separate viewing logic


(previsualization, computation) from actual
 rendering


  • iOS: DisplayLink very useful here

  • Bonus: manually decode JPEGs on a


background thread; don’t let viewer
 handle it on the fly

  • Decouple online computation (detections, 


keypoint tracking, style transfer, etc) from
 preview rendering


  • Don’t queue forever: know when to 


throttle, when to revert to offline


  • Write flexibly; remember, what looks


good on the iPhone X won’t look good 


  • n a 4s
slide-93
SLIDE 93

TIP: MEMORY MATTERS

  • iOS: @autoreleasepool, intercept 


memory warnings


  • Android: reason with the garbage collector in mind

(and the stutter it could cause)


  • Trust design patterns for asynchronous 


systems: they are *hard* to rederive 
 from scratch


  • Favor online approaches wherever


possible

slide-94
SLIDE 94

TIP: MEMORY MATTERS

  • Common mistake: bad delegate patterns
slide-95
SLIDE 95

TIP: MEMORY MATTERS

CameraViewController DGBGDetector @property (strong) ___ *detector @property (strong) ___ *delegate

Circular reference = memory leak!

slide-96
SLIDE 96

TIP: MEMORY MATTERS

CameraViewController DGBGDetector @property (strong) ___ *detector @property (weak) ___ *delegate

slide-97
SLIDE 97

TIP: MEMORY MATTERS

  • Even more nefarious: inline function blocks


self.successHandler = ^{
 _statusButton.text = @“SUCCESS!”
 }


  • Correct pattern: weak pointers


__weak typeof(self) *weakSelf = self; self.successHandler = ^{
 weakSelf.statusButton.text = @“SUCCESS!”
 }

self successHandler

@property (strong) void() * @property (strong) Controller *

weakSelf successHandler

@property (strong) void() * @property (weak) Controller *

slide-98
SLIDE 98

TIP: MEMORY MATTERS

  • Be strict:

  • Reuse large objects (i.e neural networks, filters) as

global singletons


  • Clean up unneeded memory ASAP; don’t wait for


garbage collector to get around to it

slide-99
SLIDE 99

THANKS!

  • Check us out at http://fyusion.com

  • Try our newly released Viewer SDK at http://developers.fyusion.com

  • Tweet me @sdavidmiller, find me at http://sdavidmiller.com, or…

  • Google “Stephen Miller”, and help PageRank devalue this guy: