amp

WPCampus 2019 WP Rig Workshop

This post contains the slides for and links to all the things you need to follow my WP Rig workshop at WP Campus 2019, including a couple of verbose code examples for complex walk-throughs. WP Rig itself: WP Rig WP Rig Wiki Free LinkedIn Learning course on WP Rig VS Code extensions EditorConfig ESLint PHP […]

The post WPCampus 2019 WP Rig Workshop appeared first on MOR10.




amp

The Chart Guide v4.0 - Interview & Giveaway

Michiel Dullaert, data visualization expert and trainer from the Netherlands, has updated his Chart Guide poster to version 4! A free PDF is available for download from his website, and introduces a new category, 19 new charts and 4 extra design tips. You can also purchase a full-size printed poster version.

As the November 2019 Giveaway, I have a pair of Chart Guide posters, that will be shipped to one lucky winner. That way you get one for yourself, and one you can give to a friend or coworker.

Register HERE by November 30, 2019 at 11:59pm CT, and the winner will be randomly chosen on December 1st!

This poster shows 84 charts to choose from and includes 16 chart design tips to help you make the Perfect Chart. The poster is available as a big poster or you can download the PDF file for free. Let this ChartGuide poster help you choose and design your Perfect Chart.

You can see his complete write-up about the new version HERE. I was able to ask Michiel a few interview questions about developing the posters:

Cool Infographics: What’s your background and how did you get into visualizing data?

Michiel Dullaert: Years ago I have been working in the boardgame and puzzle industry. Part of my work was discovering new boardgames and puzzles and introduce them to the market. I was working for two different companies, both at the time that a new product of theirs really changed the market. For the boardgame industry I worked for the company that introduced a new type of boardgame (the game of Catan) that made playing boardgames a popular hobby. After that, I worked for a company that created puzzle magazines at the time the Sudoku puzzles was introduced. And here the same happened again, a new type of puzzle that changed the way people would puzzle and talk about puzzles. Both were very nice jobs, with a lot of enthusiastic conversations with customers about new products.

In both companies I was working in the product development. I always had a large personal interest in the data behind the products. So it felt logic to do more with data, and I changed careers. I started working for a large company as an analyst. And it was not long that I found out that my colleagues were not interested in my reports. Although the reports contained interesting information it was shown in large tables and busy charts. People seemed to be not interested and if the looked into the numbers, they did not seem to understand them. My work did not seem to matter. The contrast between my previous jobs and the work as an analyst could not have been bigger. At that time I decided I would try to find a way to make people as enthusiastic about data as they were about boardgames and Sudoku puzzles. 

The first step was reading books on the topic of data visualization. Because I was working in the business intelligence field, the most logic choice were the books of Stephen Few. I bought them all and a whole new world opened for me. When Few was in the Netherlands to give a course I felt very lucky I could join. The workshops inspired me to learn more on this topic. So I bought more books and the next year I joined a class of Alberto Caïro. This gave me multiple perspectives on the same topic. The things I learned were applied to my work, and I was getting more and more responses on my visualizations. People actually started to read and understand them. 

My manager asked me to explain my choices in visualizations to my colleagues, so they could learn from me. And then I discovered how great it is to teach about data visualisation. I met a couple of UX designers and they inspired me learn more about that topic and to get an UX certification. The knowledge I gained in learning UX helped me in developing my own perspective on good data visualization. And in my workshop I try to inspire others to create such. For these workshops I wanted an overview of charts. Although there were already some great overviews, none of them had the point of view I was teaching in class. So I decided to design my own. That’s how Chart.Guide started. 

Cool Infographics: Who is the Chart Guide poster intended for?

Michiel Dullaert: The website and the posters are intended for everyone who makes charts. For me it does not matter if you are working as a data-journalist or a data scientist, a infographic designer, project manager or a financial analyst. As long as you need help or inspiration when making charts or tables, Chart.Guide can help you. Online in the form of the website and offline in the form of the poster. Because I want to inspire as many people as possible I made the PDF of the poster free to download. I know that the poster is used in business departments, newsrooms and in school classrooms.

Cool Infographics: What was your design process for the poster?

Michiel Dullaert: The main source for updates to the poster or website, is the conversations I have with people I teach or work with. If they have a need for certain chart types, or make design mistakes, I try to add that topic. 

DPG Chart Chooser

The first poster edition (picture DPG Chart Chooser) was just a collection of charts I created for my students. For each chart a few words on when to use the chart and, more important, it gave advice on what charts were not recommended. On the second edition (the first under the Chart.Guide brand) I added chart design tips.  The reason, I saw people choose a good chart but then mess up the design. Last year, I got questions about maps, so I decided to add them on poster edition 4. 

Rearranging the layout of the Chart Guide

The design process starts with insight I get from conversations I am having. Next step is cutting the old poster and rearranging everything. (see picture ChartGuide rearrange) now, will lead to more insights on the poster in the future. Although it make take some time to transform everything to the screen or paper. I still need to find some time to explain on the website why some charts are “not recommended”. 

Cool Infographics: You asked your followers to help choose the design of the new poster. How did that go?

Michiel Dullaert: The poster is made to help people. So it seems to be logic to give them a role in the design process. As a UX designer I like to test my designs before releasing them. Most of these tests are done in class, because I like to observe the users in how they use the new design. The online voting was suggestion of a student. It did give me a lot of useful feedback. Especially when people wrote a lot of text explaining their choice. For future editions I will do the same.

Cool Infographics: How can people follow you for updates?

Michiel Dullaert: People who have downloaded the PDF will get an email when a new poster is available, or when something interesting is added to the website. For this and more chart related inspiration, they can follow me on Twitter: @Chart_Guide or on facebook: /ChartGuide1.

This helpful reference guide is one of over 25 FREE data visualization guides I maintain links to in the Cool Infographics Tools pages. See them all on the DataViz Reference Guides page, and let me know if I’m missing any.




amp

SS Peter & Paul

Andrew Rickmann posted a photo:

SS Peter and Paul in Wantage, Oxfordshire.




amp

5 Critical Lessons Learned Organizing WordCamp Ann Arbor for the Third Time

In early 2014 I had just gotten married and recently moved into a new home. With two major life events out of the way, I decided I was ready to lead a WordCamp. I originally planned to organize WordCamp Detroit. I was an organizer twice before and the event had missed a year and I […]

The post 5 Critical Lessons Learned Organizing WordCamp Ann Arbor for the Third Time appeared first on Psychology of Web Design | 3.7 Blog.




amp

It’s A Living Mural for X-Games China & Innersect

It’s A Living Mural for X-Games China & Innersect

AoiroStudioMay 05, 2020

I think Fabio and I are on a challenge to keep the ABDZ homepage in color tones of 'pastel visuals'. It's perfect because I stumbled across the new project from It's A Living aka Ricardo Gonzalez for X-Games China & Innersect 2019 in Shanghai, China. I don't know if you are familiar or not by Ricardo's distinct lettering style but it's just plain beautiful and vibrant. INNERSECT is the biggest street culture convention in China, a street fashion project founded by celebrity icon Edison Chen in 2017. Feast your eyes!

About It’s A Living

AKA Ricardo Gonzalez is an incredible artist who has worked through many collaborations and his lettering style is so unique. Make sure to check out his links.




amp

12 Best GoDaddy Alternatives for Domain & Web Hosting (2020)

Are you looking for the best GoDaddy alternative for domain registration and web hosting? Without a doubt, Godaddy is one of the most popular names when it comes to registering domain names and hosting your business online. Over the last 22 years, GoDaddy has managed to establish a stronghold in the market. In this article, […]

The post 12 Best GoDaddy Alternatives for Domain & Web Hosting (2020) appeared first on IsItWP - Free WordPress Theme Detector.




amp

Reestablishing a Social Life on Campus with Other Veterans and Civilians Post-TBI

Transitioning from military to civilian life can take time and can be tricky. Adam talks about how student veteran groups on college campuses can help vets reintegrate socially in their own way and  time.




amp

Test or Meet at WordCamp San Francisco and Win a Plugin License!

Next week I will be at WordCamp San Francisco and a week later at the WooConf! Maybe one or antoher […]




amp

Want to help the USPS and vets? Buy a 'Healing PTSD' stamp

Support two entities with the price of one.





amp

Intuition, Creative Freedom & Doing What You Love with Chris Ballew

Today’s episode is going to rock your world … pun fully intended because today’s guest is an actual rock star. You may remember a band called Presidents of the United States of America. They took the world by storm in 1995 with their self titled album, Presidents of the United States of America playing songs like Lump and Peaches. Yes, that’s right. My guest today is frontman Chris Ballew. Chris and I have been friends for years, including collaborating on a music video together and at least one live performance (gotta listen to find out ;). Of course we get into his musical journey, a meteoric rise to success, and then realizing something was missing. We take some deep dives into Chris’ creative process, including his method for capturing his small bits and later using those to write new works, including his new project Casper Babypants. In this episode: Consider what kind of artist you are and how you relate to other artists. For years Chris played in bands, but what he learned about himself is his work is actually solo. Don’t censor yourself while you’re creating. Get it out, no matter how crazy or ridiculous or unusual and then […]

The post Intuition, Creative Freedom & Doing What You Love with Chris Ballew appeared first on Chase Jarvis Photography.




amp

Concurrency & Multithreading in iOS

Concurrency is the notion of multiple things happening at the same time. This is generally achieved either via time-slicing, or truly in parallel if multiple CPU cores are available to the host operating system. We've all experienced a lack of concurrency, most likely in the form of an app freezing up when running a heavy task. UI freezes don't necessarily occur due to the absence of concurrency — they could just be symptoms of buggy software — but software that doesn't take advantage of all the computational power at its disposal is going to create these freezes whenever it needs to do something resource-intensive. If you've profiled an app hanging in this way, you'll probably see a report that looks like this:

Anything related to file I/O, data processing, or networking usually warrants a background task (unless you have a very compelling excuse to halt the entire program). There aren't many reasons that these tasks should block your user from interacting with the rest of your application. Consider how much better the user experience of your app could be if instead, the profiler reported something like this:

Analyzing an image, processing a document or a piece of audio, or writing a sizeable chunk of data to disk are examples of tasks that could benefit greatly from being delegated to background threads. Let's dig into how we can enforce such behavior into our iOS applications.


A Brief History

In the olden days, the maximum amount of work per CPU cycle that a computer could perform was determined by the clock speed. As processor designs became more compact, heat and physical constraints started becoming limiting factors for higher clock speeds. Consequentially, chip manufacturers started adding additional processor cores on each chip in order to increase total performance. By increasing the number of cores, a single chip could execute more CPU instructions per cycle without increasing its speed, size, or thermal output. There's just one problem...

How can we take advantage of these extra cores? Multithreading.

Multithreading is an implementation handled by the host operating system to allow the creation and usage of n amount of threads. Its main purpose is to provide simultaneous execution of two or more parts of a program to utilize all available CPU time. Multithreading is a powerful technique to have in a programmer's toolbelt, but it comes with its own set of responsibilities. A common misconception is that multithreading requires a multi-core processor, but this isn't the case — single-core CPUs are perfectly capable of working on many threads, but we'll take a look in a bit as to why threading is a problem in the first place. Before we dive in, let's look at the nuances of what concurrency and parallelism mean using a simple diagram:

In the first situation presented above, we observe that tasks can run concurrently, but not in parallel. This is similar to having multiple conversations in a chatroom, and interleaving (context-switching) between them, but never truly conversing with two people at the same time. This is what we call concurrency. It is the illusion of multiple things happening at the same time when in reality, they're switching very quickly. Concurrency is about dealing with lots of things at the same time. Contrast this with the parallelism model, in which both tasks run simultaneously. Both execution models exhibit multithreading, which is the involvement of multiple threads working towards one common goal. Multithreading is a generalized technique for introducing a combination of concurrency and parallelism into your program.


The Burden of Threads

A modern multitasking operating system like iOS has hundreds of programs (or processes) running at any given moment. However, most of these programs are either system daemons or background processes that have very low memory footprint, so what is really needed is a way for individual applications to make use of the extra cores available. An application (process) can have many threads (sub-processes) operating on shared memory. Our goal is to be able to control these threads and use them to our advantage.

Historically, introducing concurrency to an app has required the creation of one or more threads. Threads are low-level constructs that need to be managed manually. A quick skim through Apple's Threaded Programming Guide is all it takes to see how much complexity threaded code adds to a codebase. In addition to building an app, the developer has to:

  • Responsibly create new threads, adjusting that number dynamically as system conditions change
  • Manage them carefully, deallocating them from memory once they have finished executing
  • Leverage synchronization mechanisms like mutexes, locks, and semaphores to orchestrate resource access between threads, adding even more overhead to application code
  • Mitigate risks associated with coding an application that assumes most of the costs associated with creating and maintaining any threads it uses, and not the host OS

This is unfortunate, as it adds enormous levels of complexity and risk without any guarantees of improved performance.


Grand Central Dispatch

iOS takes an asynchronous approach to solving the concurrency problem of managing threads. Asynchronous functions are common in most programming environments, and are often used to initiate tasks that might take a long time, like reading a file from the disk, or downloading a file from the web. When invoked, an asynchronous function executes some work behind the scenes to start a background task, but returns immediately, regardless of how long the original task might takes to actually complete.

A core technology that iOS provides for starting tasks asynchronously is Grand Central Dispatch (or GCD for short). GCD abstracts away thread management code and moves it down to the system level, exposing a light API to define tasks and execute them on an appropriate dispatch queue. GCD takes care of all thread management and scheduling, providing a holistic approach to task management and execution, while also providing better efficiency than traditional threads.

Let's take a look at the main components of GCD:

What've we got here? Let's start from the left:

  • DispatchQueue.main: The main thread, or the UI thread, is backed by a single serial queue. All tasks are executed in succession, so it is guaranteed that the order of execution is preserved. It is crucial that you ensure all UI updates are designated to this queue, and that you never run any blocking tasks on it. We want to ensure that the app's run loop (called CFRunLoop) is never blocked in order to maintain the highest framerate. Subsequently, the main queue has the highest priority, and any tasks pushed onto this queue will get executed immediately.
  • DispatchQueue.global: A set of global concurrent queues, each of which manage their own pool of threads. Depending on the priority of your task, you can specify which specific queue to execute your task on, although you should resort to using default most of the time. Because tasks on these queues are executed concurrently, it doesn't guarantee preservation of the order in which tasks were queued.

Notice how we're not dealing with individual threads anymore? We're dealing with queues which manage a pool of threads internally, and you will shortly see why queues are a much more sustainable approach to multhreading.

Serial Queues: The Main Thread

As an exercise, let's look at a snippet of code below, which gets fired when the user presses a button in the app. The expensive compute function can be anything. Let's pretend it is post-processing an image stored on the device.

import UIKit

class ViewController: UIViewController {
    @IBAction func handleTap(_ sender: Any) {
        compute()
    }

    private func compute() -> Void {
        // Pretending to post-process a large image.
        var counter = 0
        for _ in 0..<9999999 {
            counter += 1
        }
    }
}

At first glance, this may look harmless, but if you run this inside of a real app, the UI will freeze completely until the loop is terminated, which will take... a while. We can prove it by profiling this task in Instruments. You can fire up the Time Profiler module of Instruments by going to Xcode > Open Developer Tool > Instruments in Xcode's menu options. Let's look at the Threads module of the profiler and see where the CPU usage is highest.

We can see that the Main Thread is clearly at 100% capacity for almost 5 seconds. That's a non-trivial amount of time to block the UI. Looking at the call tree below the chart, we can see that the Main Thread is at 99.9% capacity for 4.43 seconds! Given that a serial queue works in a FIFO manner, tasks will always complete in the order in which they were inserted. Clearly the compute() method is the culprit here. Can you imagine clicking a button just to have the UI freeze up on you for that long?

Background Threads

How can we make this better? DispatchQueue.global() to the rescue! This is where background threads come in. Referring to the GCD architecture diagram above, we can see that anything that is not the Main Thread is a background thread in iOS. They can run alongside the Main Thread, leaving it fully unoccupied and ready to handle other UI events like scrolling, responding to user events, animating etc. Let's make a small change to our button click handler above:

class ViewController: UIViewController {
    @IBAction func handleTap(_ sender: Any) {
        DispatchQueue.global(qos: .userInitiated).async { [unowned self] in
            self.compute()
        }
    }

    private func compute() -> Void {
        // Pretending to post-process a large image.
        var counter = 0
        for _ in 0..<9999999 {
            counter += 1
        }
    }
}

Unless specified, a snippet of code will usually default to execute on the Main Queue, so in order to force it to execute on a different thread, we'll wrap our compute call inside of an asynchronous closure that gets submitted to the DispatchQueue.global queue. Keep in mind that we aren't really managing threads here. We're submitting tasks (in the form of closures or blocks) to the desired queue with the assumption that it is guaranteed to execute at some point in time. The queue decides which thread to allocate the task to, and it does all the hard work of assessing system requirements and managing the actual threads. This is the magic of Grand Central Dispatch. As the old adage goes, you can't improve what you can't measure. So we measured our truly terrible button click handler, and now that we've improved it, we'll measure it once again to get some concrete data with regards to performance.

Looking at the profiler again, it's quite clear to us that this is a huge improvement. The task takes an identical amount of time, but this time, it's happening in the background without locking up the UI. Even though our app is doing the same amount of work, the perceived performance is much better because the user will be free to do other things while the app is processing.

You may have noticed that we accessed a global queue of .userInitiated priority. This is an attribute we can use to give our tasks a sense of urgency. If we run the same task on a global queue of and pass it a qos attribute of background , iOS will think it's a utility task, and thus allocate fewer resources to execute it. So, while we don't have control over when our tasks get executed, we do have control over their priority.

A Note on Main Thread vs. Main Queue

You might be wondering why the Profiler shows "Main Thread" and why we're referring to it as the "Main Queue". If you refer back to the GCD architecture we described above, the Main Queue is solely responsible for managing the Main Thread. The Dispatch Queues section in the Concurrency Programming Guide says that "the main dispatch queue is a globally available serial queue that executes tasks on the application’s main thread. Because it runs on your application’s main thread, the main queue is often used as a key synchronization point for an application."

The terms "execute on the Main Thread" and "execute on the Main Queue" can be used interchangeably.


Concurrent Queues

So far, our tasks have been executed exclusively in a serial manner. DispatchQueue.main is by default a serial queue, and DispatchQueue.global gives you four concurrent dispatch queues depending on the priority parameter you pass in.

Let's say we want to take five images, and have our app process them all in parallel on background threads. How would we go about doing that? We can spin up a custom concurrent queue with an identifier of our choosing, and allocate those tasks there. All that's required is the .concurrent attribute during the construction of the queue.

class ViewController: UIViewController {
    let queue = DispatchQueue(label: "com.app.concurrentQueue", attributes: .concurrent)
    let images: [UIImage] = [UIImage].init(repeating: UIImage(), count: 5)

    @IBAction func handleTap(_ sender: Any) {
        for img in images {
            queue.async { [unowned self] in
                self.compute(img)
            }
        }
    }

    private func compute(_ img: UIImage) -> Void {
        // Pretending to post-process a large image.
        var counter = 0
        for _ in 0..<9999999 {
            counter += 1
        }
    }
}

Running that through the profiler, we can see that the app is now spinning up 5 discrete threads to parallelize a for-loop.

Parallelization of N Tasks

So far, we've looked at pushing computationally expensive task(s) onto background threads without clogging up the UI thread. But what about executing parallel tasks with some restrictions? How can Spotify download multiple songs in parallel, while limiting the maximum number up to 3? We can go about this in a few ways, but this is a good time to explore another important construct in multithreaded programming: semaphores.

Semaphores are signaling mechanisms. They are commonly used to control access to a shared resource. Imagine a scenario where a thread can lock access to a certain section of the code while it executes it, and unlocks after it's done to let other threads execute the said section of the code. You would see this type of behavior in database writes and reads, for example. What if you want only one thread writing to a database and preventing any reads during that time? This is a common concern in thread-safety called Readers-writer lock. Semaphores can be used to control concurrency in our app by allowing us to lock n number of threads.

let kMaxConcurrent = 3 // Or 1 if you want strictly ordered downloads!
let semaphore = DispatchSemaphore(value: kMaxConcurrent)
let downloadQueue = DispatchQueue(label: "com.app.downloadQueue", attributes: .concurrent)

class ViewController: UIViewController {
    @IBAction func handleTap(_ sender: Any) {
        for i in 0..<15 {
            downloadQueue.async { [unowned self] in
                // Lock shared resource access
                semaphore.wait()

                // Expensive task
                self.download(i + 1)

                // Update the UI on the main thread, always!
                DispatchQueue.main.async {
                    tableView.reloadData()

                    // Release the lock
                    semaphore.signal()
                }
            }
        }
    }

    func download(_ songId: Int) -> Void {
        var counter = 0

        // Simulate semi-random download times.
        for _ in 0..<Int.random(in: 999999...10000000) {
            counter += songId
        }
    }
}

Notice how we've effectively restricted our download system to limit itself to k number of downloads. The moment one download finishes (or thread is done executing), it decrements the semaphore, allowing the managing queue to spawn another thread and start downloading another song. You can apply a similar pattern to database transactions when dealing with concurrent reads and writes.

Semaphores usually aren't necessary for code like the one in our example, but they become more powerful when you need to enforce synchronous behavior whille consuming an asynchronous API. The above could would work just as well with a custom NSOperationQueue with a maxConcurrentOperationCount, but it's a worthwhile tangent regardless.


Finer Control with OperationQueue

GCD is great when you want to dispatch one-off tasks or closures into a queue in a 'set-it-and-forget-it' fashion, and it provides a very lightweight way of doing so. But what if we want to create a repeatable, structured, long-running task that produces associated state or data? And what if we want to model this chain of operations such that they can be cancelled, suspended and tracked, while still working with a closure-friendly API? Imagine an operation like this:

This would be quite cumbersome to achieve with GCD. We want a more modular way of defining a group of tasks while maintaining readability and also exposing a greater amount of control. In this case, we can use Operation objects and queue them onto an OperationQueue, which is a high-level wrapper around DispatchQueue. Let's look at some of the benefits of using these abstractions and what they offer in comparison to the lower-level GCI API:

  • You may want to create dependencies between tasks, and while you could do this via GCD, you're better off defining them concretely as Operation objects, or units of work, and pushing them onto your own queue. This would allow for maximum reusability since you may use the same pattern elsewhere in an application.
  • The Operation and OperationQueue classes have a number of properties that can be observed, using KVO (Key Value Observing). This is another important benefit if you want to monitor the state of an operation or operation queue.
  • Operations can be paused, resumed, and cancelled. Once you dispatch a task using Grand Central Dispatch, you no longer have control or insight into the execution of that task. The Operation API is more flexible in that respect, giving the developer control over the operation's life cycle.
  • OperationQueue allows you to specify the maximum number of queued operations that can run simultaneously, giving you a finer degree of control over the concurrency aspects.

The usage of Operation and OperationQueue could fill an entire blog post, but let's look at a quick example of what modeling dependencies looks like. (GCD can also create dependencies, but you're better off dividing up large tasks into a series of composable sub-tasks.) In order to create a chain of operations that depend on one another, we could do something like this:

class ViewController: UIViewController {
    var queue = OperationQueue()
    var rawImage = UIImage? = nil
    let imageUrl = URL(string: "https://example.com/portrait.jpg")!
    @IBOutlet weak var imageView: UIImageView!

    let downloadOperation = BlockOperation {
        let image = Downloader.downloadImageWithURL(url: imageUrl)
        OperationQueue.main.async {
            self.rawImage = image
        }
    }

    let filterOperation = BlockOperation {
        let filteredImage = ImgProcessor.addGaussianBlur(self.rawImage)
        OperationQueue.main.async {
            self.imageView = filteredImage
        }
    }

    filterOperation.addDependency(downloadOperation)

    [downloadOperation, filterOperation].forEach {
        queue.addOperation($0)
     }
}

So why not opt for a higher level abstraction and avoid using GCD entirely? While GCD is ideal for inline asynchronous processing, Operation provides a more comprehensive, object-oriented model of computation for encapsulating all of the data around structured, repeatable tasks in an application. Developers should use the highest level of abstraction possible for any given problem, and for scheduling consistent, repeated work, that abstraction is Operation. Other times, it makes more sense to sprinkle in some GCD for one-off tasks or closures that we want to fire. We can mix both OperationQueue and GCD to get the best of both worlds.


The Cost of Concurrency

DispatchQueue and friends are meant to make it easier for the application developer to execute code concurrently. However, these technologies do not guarantee improvements to the efficiency or responsiveness in an application. It is up to you to use queues in a manner that is both effective and does not impose an undue burden on other resources. For example, it's totally viable to create 10,000 tasks and submit them to a queue, but doing so would allocate a nontrivial amount of memory and introduce a lot of overhead for the allocation and deallocation of operation blocks. This is the opposite of what you want! It's best to profile your app thoroughly to ensure that concurrency is enhancing your app's performance and not degrading it.

We've talked about how concurrency comes at a cost in terms of complexity and allocation of system resources, but introducing concurrency also brings a host of other risks like:

  • Deadlock: A situation where a thread locks a critical portion of the code and can halt the application's run loop entirely. In the context of GCD, you should be very careful when using the dispatchQueue.sync { } calls as you could easily get yourself in situations where two synchronous operations can get stuck waiting for each other.
  • Priority Inversion: A condition where a lower priority task blocks a high priority task from executing, which effectively inverts their priorities. GCD allows for different levels of priority on its background queues, so this is quite easily a possibility.
  • Producer-Consumer Problem: A race condition where one thread is creating a data resource while another thread is accessing it. This is a synchronization problem, and can be solved using locks, semaphores, serial queues, or a barrier dispatch if you're using concurrent queues in GCD.
  • ...and many other sorts of locking and data-race conditions that are hard to debug! Thread safety is of the utmost concern when dealing with concurrency.

Parting Thoughts + Further Reading

If you've made it this far, I applaud you. Hopefully this article gives you a lay of the land when it comes to multithreading techniques on iOS, and how you can use some of them in your app. We didn't get to cover many of the lower-level constructs like locks, mutexes and how they help us achieve synchronization, nor did we get to dive into concrete examples of how concurrency can hurt your app. We'll save those for another day, but you can dig into some additional reading and videos if you're eager to dive deeper.




amp

CLI Equivalents for Common MAMP PRO and Sequel Pro Tasks

Working on website front ends I sometimes use MAMP PRO to manage local hosts and Sequel Pro to manage databases. Living primarily in my text editor, a terminal, and a browser window, moving to these click-heavy dedicated apps can feel clunky. Happily, the tasks I have most frequently turned to those apps for —starting and stopping servers, creating new hosts, and importing, exporting, deleting, and creating databases— can be done from the command line.

I still pull up MAMP PRO if I need to change a host's PHP version or work with its other more specialized settings, or Sequel Pro to quickly inspect a database, but for the most part I can stay on the keyboard and in my terminal. Here's how:

Command Line MAMP PRO

You can start and stop MAMP PRO's servers from the command line. You can even do this when the MAMP PRO desktop app isn't open.

Note: MAMP PRO's menu icon will not change color to reflect the running/stopped status when the status is changed via the command line.

  • Start the MAMP PRO servers:
/Applications/MAMP PRO.app/Contents/MacOS/MAMP PRO cmd startServers
  • Stop the MAMP PRO servers:
/Applications/MAMP PRO.app/Contents/MacOS/MAMP PRO cmd stopServers
  • Create a host (replace host_name and root_path):
/Applications/MAMP PRO.app/Contents/MacOS/MAMP PRO cmd createHost host_name root_path

MAMP PRO-friendly Command Line Sequel Pro

Note: if you don't use MAMP PRO, just replace the /Applications/MAMP/Library/bin/mysql with mysql.

In all of the following commands, replace username with your user name (locally this is likely root) and database_name with your database name. The -p (password) flag with no argument will trigger an interactive password prompt. This is more secure than including your password in the command itself (like -pYourPasswordHere). Of course, if you're using the default password root is not particular secure to begin with so you might just do -pYourPasswordHere.

Setting the -h (host) flag to localhost or 127.0.0.1 tells mysql to look at what's on localhost. With the MAMP PRO servers running, that will be the MAMP PRO databases.

# with the MAMP PRO servers running, these are equivalent:
# /Applications/MAMP/Library/bin/mysql -h 127.0.0.1 other_options
# and
# /Applications/MAMP/Library/bin/mysql -h localhost other_options

/Applications/MAMP/Library/bin/mysql mysql_options # enter. opens an interactive mysql session
mysql> some command; # don't forget the semicolon
mysql> exit;
  • Create a local database
# with the MAMP PRO servers running
# replace `username` with your username, which is `root` by default
/Applications/MAMP/Library/bin/mysql -h localhost -u username -p -e "create database database_name"

or

# with the MAMP PRO servers running
# replace `username` (`root` by default) and `database_name`
/Applications/MAMP/Library/bin/mysql -h localhost -u username -p # and then enter
mysql> create database database_name; # don't forget the semicolon
mysql> exit

    MAMP PRO's databases are stored in /Library/Application Support/appsolute/MAMP PRO/db so to confirm that it worked you can

ls /Library/Application Support/appsolute/MAMP PRO/db
# will output the available mysql versions. For example I have
mysql56_2018-11-05_16-25-13     mysql57

# If it isn't clear which one you're after, open the main MAMP PRO and click
# on the MySQL "servers and services" item. In my case it shows "Version: 5.7.26"

# Now look in the relevant MySQL directory
ls /Library/Application Support/appsolute/MAMP PRO/db/mysql57
# the newly created database should be in the list
  • Delete a local database
# with the MAMP PRO servers running
# replace `username` (`root` by default) and `database_name`
/Applications/MAMP/Library/bin/mysql -h localhost -u username -p -e "drop database database_name"
  • Export a dump of a local database. Note that this uses mysqldump not mysql.
# to export an uncompressed file
# replace `username` (`root` by default) and `database_name`
/Applications/MAMP/Library/bin/mysqldump -h localhost -u username -p database_name > the/output/path.sql

# to export a compressed file
# replace `username` (`root` by default) and `database_name`
/Applications/MAMP/Library/bin/mysqldump -h localhost -u username -p database_name | gzip -c > the/output/path.gz

  • Export a local dump from an external database over SSH. Note that this uses mysqldump not mysql.

# replace `ssh-user`, `ssh_host`, `mysql_user`, `database_name`, and the output path

# to end up with an uncompressed file
ssh ssh_user@ssh_host "mysqldump -u mysql_user -p database_name | gzip -c" | gunzip > the/output/path.sql

# to end up with a compressed file
ssh ssh_user@ssh_host "mysqldump -u mysql_user -p database_name | gzip -c" > the/output/path.gz
  • Import a local database dump into a local database
# with the MAMP PRO servers running
# replace `username` (`root` by default) and `database_name`
/Applications/MAMP/Library/bin/mysql -h localhost -u username -p database_name < the/dump/path.sql
  • Import a local database dump into a remote database over SSH. Use care with this one. But if you are doing it with Sequel Pro —maybe you are copying a Craft site's database from a production server to a QA server— you might as well be able to do it on the command line.
ssh ssh_user@ssh_host "mysql -u username -p remote_database_name" < the/local/dump/path.sql


For me, using the command line instead of the MAMP PRO and Sequel Pro GUI means less switching between keyboard and mouse, less opening up GUI features that aren't typically visible on my screen, and generally better DX. Give it a try! And while MAMP Pro's CLI is limited to the essentials, command line mysql of course knows no limits. If there's something else you use Sequel Pro for, you may be able to come up with a mysql CLI equivalent you like even better.



  • Code
  • Front-end Engineering
  • Back-end Engineering

amp

10 Cool & Free Mobile Wallpapers

Guys, great news! Our friends at Freepik has released exclusively for s2o readers 10 Cool & Free Mobile Wallpapers in several awesome styles. They come in AI, EPS and jpg files. The wallpapers are easily resizable for any kind of mobile —or any other project ;)— so you can adapt them in a no time …

10 Cool & Free Mobile Wallpapers Read More »






amp

On the finiteness of ample models. (arXiv:2005.02613v2 [math.AG] UPDATED)

In this paper, we generalize the finiteness of models theorem in [BCHM06] to Kawamata log terminal pairs with fixed Kodaira dimension. As a consequence, we prove that a Kawamata log terminal pair with $mathbb{R}-$boundary has a canonical model, and can be approximated by log pairs with $mathbb{Q}-$boundary and the same canonical model.




amp

Set theoretic Yang-Baxter & reflection equations and quantum group symmetries. (arXiv:2003.08317v3 [math-ph] UPDATED)

Connections between set theoretic Yang-Baxter and reflection equations and quantum integrable systems are investigated. We show that set theoretic $R$-matrices are expressed as twists of known solutions. We then focus on reflection and twisted algebras and we derive the associated defining algebra relations for $R$-matrices being Baxterized solutions of the $A$-type Hecke algebra ${cal H}_N(q=1)$. We show in the case of the reflection algebra that there exists a "boundary" finite sub-algebra for some special choice of "boundary" elements of the $B$-type Hecke algebra ${cal B}_N(q=1, Q)$. We also show the key proposition that the associated double row transfer matrix is essentially expressed in terms of the elements of the $B$-type Hecke algebra. This is one of the fundamental results of this investigation together with the proof of the duality between the boundary finite subalgebra and the $B$-type Hecke algebra. These are universal statements that largely generalize previous relevant findings, and also allow the investigation of the symmetries of the double row transfer matrix.




amp

Integrability of moduli and regularity of Denjoy counterexamples. (arXiv:1908.06568v4 [math.DS] UPDATED)

We study the regularity of exceptional actions of groups by $C^{1,alpha}$ diffeomorphisms on the circle, i.e. ones which admit exceptional minimal sets, and whose elements have first derivatives that are continuous with concave modulus of continuity $alpha$. Let $G$ be a finitely generated group admitting a $C^{1,alpha}$ action $ ho$ with a free orbit on the circle, and such that the logarithms of derivatives of group elements are uniformly bounded at some point of the circle. We prove that if $G$ has spherical growth bounded by $c n^{d-1}$ and if the function $1/alpha^d$ is integrable near zero, then under some mild technical assumptions on $alpha$, there is a sequence of exceptional $C^{1,alpha}$ actions of $G$ which converge to $ ho$ in the $C^1$ topology. As a consequence for a single diffeomorphism, we obtain that if the function $1/alpha$ is integrable near zero, then there exists a $C^{1,alpha}$ exceptional diffeomorphism of the circle. This corollary accounts for all previously known moduli of continuity for derivatives of exceptional diffeomorphisms. We also obtain a partial converse to our main result. For finitely generated free abelian groups, the existence of an exceptional action, together with some natural hypotheses on the derivatives of group elements, puts integrability restrictions on the modulus $alpha$. These results are related to a long-standing question of D. McDuff concerning the length spectrum of exceptional $C^1$ diffeomorphisms of the circle.




amp

7 Examples of Great “About Us” Pages

Your website serves several important purposes for your company — attracting customers, generating leads, and making sales, just to name a few. And as your home on the Internet, it also needs to explain who you are to the world and why they should choose you over your competitors.   However, creating an “About Us” […]

The post 7 Examples of Great “About Us” Pages appeared first on WebFX Blog.




amp

Category Page Design Examples: 6 Category Page Inspirations

Dozens of people find your business when looking for a type of product but aren’t sure which product fits their needs best. With a well-designed and organized category page, you’ll help people browse products easier and find what they want. To help you get inspired, let’s take a look at some excellent category page design […]

The post Category Page Design Examples: 6 Category Page Inspirations appeared first on WebFX Blog.




amp

6 Best CMS Software for Website Development & SMBs

Are you looking for a content management system (CMS) that will help you create the digital content you need? With so many options on the market, it’s challenging to know which one is the best CMS software for your business. On this page, we’ll take a look at the six best CMS’s for website development […]

The post 6 Best CMS Software for Website Development & SMBs appeared first on WebFX Blog.




amp

6 Service Page Web Design Examples to Inspire You

Did you know that 75% of opinions on website credibility comes from design? If you want people to look at your services and find you credible, you must invest in web design for services pages to provide your audience with a positive experience. By looking at some web design examples for service pages, you’ll get […]

The post 6 Service Page Web Design Examples to Inspire You appeared first on WebFX Blog.




amp

5 Magnificent Examples of Websites That Convert Visitors into Customers

Need some inspiration to build a high converting website? Websites that convert persuade visitors to become customers. These websites drive more revenue, so if you want to increase your site’s revenue, use these examples of websites that convert as inspiration! We’ll go over what makes for the best converting websites and five examples of websites […]

The post 5 Magnificent Examples of Websites That Convert Visitors into Customers appeared first on WebFX Blog.




amp

Beginners Guide to CSS Flexbox With Examples

Flexbox is not a single property; it's a complete module that comes with a number of features. In this article, we will look at a complete guide for CSS Flexbox.

Before going into detail, I just want to answer why we should use flexbox layout instead of a traditional way of doing layout webpage using display properties, float properties, positional properties




amp

Regional summer camps hope the pandemic doesn't put activities on pause, but have backup plans ready if it does

[IMAGE-1]After having their school year totally disrupted by the coronavirus pandemic, a return to some semblance of normalcy come summer is all many school-age kids and their families are looking forward to. For many, this anticipation includes annual summer camp traditions, from sleep-away adventures on the lake to fun-filled day camps for arts, learning or team sports.…




amp

A guide to the Inlander's list of 2020 summer camps

Summer Camps 2020 "Regional Summer Camps Hope the Pandemic Doesn't Put Activities on Pause, But Have Backup Plans Ready if it Does" …




amp

Don't expect any socially distanced Zags games in the Kennel next year, and other thoughts from Gonzaga Athletic Director Mike Roth's online Q&A

Gonzaga Athletic Director Mike Roth took to the Zoom online meeting app Wednesday for a lengthy chat with members of the school community, fans and media to answer questions about college sports in the era of COVID-19. Like so many things regarding the coronavirus, there are a lot of hopes for a rapid return to normalcy — all of them couched in the reality that none of us really know how the pandemic is going to affect our lives three months from now, or six months down the line.…




amp

What will Northern Quest Resort & Casino look like when it reopens Tuesday?

Northern Quest Resort & Casino is set to reopen Tuesday, albeit with strict social-distancing and other safety protocols in place, becoming the second regional casino to reopen after closures caused by the coronavirus. Resort officials expect a crowd due to pent-up interest in the community for getting out of the house (not to mention Cinco de Mayo).…




amp

New reads from Emily St. John Mandel, vampy vibes in FX's mockumentary, and more you need to know

The Buzz Bin VAMPY VIBES…



  • Culture/Arts & Culture

amp

Best Local Coffee Roaster & Best Local Coffee Chain: Thomas Hammer Coffee

During the late '80s, Thomas Hammer got a job at the mobile coffee bar outside Nordstrom in downtown Spokane.…




amp

The Zags are the WCC champs. But why was this season so surprising?

It’s March. The regular season is now in the rearview mirror.…




amp

'We obviously have a Camp Hope 2.0-type situation': photos from Thursday night's homeless camp police confrontation

At around 5:30 pm on Thursday, there were two camps of people set up in Coeur d'Alene Park in Browne's Addition.…



  • News/Local News

amp

Classifying unclassified samples

A system and method for classifying unclassified samples. The method includes detecting a number of classes including training samples in training data sets. The method includes, for each class, determining a vector for each training sample based on a specified number of nearest neighbor distances between the training sample and neighbor training samples, and determining a class distribution based on the vectors. The method also includes detecting an unclassified sample in a data set and, for each class, determining a vector for the unclassified sample based on the specified number of nearest neighbor distances between the unclassified sample and nearest neighbor training samples within the class, and determining a probability that the unclassified sample is a member of the class based on the vector and the class distribution. The method further includes classifying the unclassified sample based on the probabilities.




amp

Amphiphilic and non-water soluble (meth)acrylic comb polymers

Non water-soluble polymers with a comb structure and a (meth)acrylic skeleton on which are grafted side chains containing at least one hydrophobic monomer of the styrene or (meth)acrylic ester type on C1 to C4, and at least one hydroxy or methoxy polylakylene glycol monomer. The levels of monomers are such that the polymer is amphiphilic because it is both rich in hydrophobic monomer and polylakylene glycol monomer. These products, used in paper coating dispersions, enable an increase in their Brookfield™ viscosity, a reduction in their ACAV viscosity, and an improvement in their water retention, which makes them particularly well suited for dry extract and/or high deposit speed coatings.




amp

Process for the oxidation of cyclohexanone to &egr -caprolactone

This invention relates to a composition comprising antimony trifluoride and silica, a method for the preparation of said composition and use of said composition as a catalyst in a process for the oxidation of cyclohexanone to ε-caprolactone.




amp

Phosphorylcholine-based amphiphilic silicones for medical applications

Amphiphilic biomimetic phosphorylcholine-containing silicone compounds for use in both topical and internal applications as components in biomedical devices. The silicone compounds, which include zwitterionic phosphorylcholine groups, may be polymerizable or non-polymerizable. Specific examples of applications include use as active functional components in ophthalmic lenses, ophthalmic lens care solutions, liquid bandages, wound dressings, and lubricious and anti-thrombogenic coatings.




amp

Phase-to-amplitude converter for direct digital synthesizer (DDS) with reduced AND and reconstructed ADD logic arrays

A sine wave generator for a Direct Digital Synthesizer (DDS) converts a digital phase input into a digital sine wave output. Sine values and slopes are stored in read-only memory (ROM) for coarse upper phase bits in a first quadrant. A quadrant folder and phase splitter reflects and inverts values from the first quadrant to generate amplitudes for all four quadrants. Each sine value and slope is stored for a range of lower phase bits. A Delta bit separates upper and lower phase bits. Delta conditionally inverts the lower phase bits, the sine value, and the final polarity. A reduced AND logic array multiplies the slope by the conditionally inverted lower phase bits. A reconstructed ADD logic array then adds the conditionally inverted sine value. The conditionally inverted polarity is added to generate the final sine value. Sine generation logic is streamlined with conditional inversion based on the Delta bit.




amp

Combination of crosslinked cationic and ampholytic polymers for personal and household applications

A cleansing composition for cosmetic or household use may include an ampholytic polymer; a crosslinked cationic polymer; a surfactant component selected from the group consisting of anionic surfactants, amphoteric surfactants, cationic surfactants, nonionic surfactants, and zwitterionic surfactants; and an aqueous and/or organic carrier.




amp

High temperature superconducting tape conductor having high critical ampacity

The invention relates to a high temperature superconducting tape conductor having a flexible metal substrate that comprises at least one intermediate layer disposed on the flexible metal substrate and comprising terraces on the side opposite the flexible metal substrate, wherein a mean width of the terraces is less than 1 μm and a mean height of the terraces is more than 20 nm, and that comprises at least one high temperature superconducting layer disposed on the intermediate layer, which is disposed on the at least one intermediate layer and comprises a layer thickness of more than 3 μm. The ampacity of the high temperature superconducting tape conductor relative to the conductor width is more than 600 A/cm at 77 K.




amp

Combined table lamp and clock assembly

A combined table lamp and clock assembly includes a lamp unit and a clock unit. The lamp unit includes a lamp stand base, a lamp stand, and a lamp bulb holder. The lamp stand base has a top side formed with a cavity, and a bottom side adapted to be placed on a table top. The lamp stand extends uprightly from the lamp stand base, and has an upper end portion and a lower end portion that is mounted on the top side of the lamp stand base. The lamp bulb holder is mounted on the upper end portion of the lamp stand, and is adapted for mounting a lamp bulb thereon. The clock unit includes a clock base, an upright clock panel, and a clock mechanism. The clock base is received in the cavity in the top side of the lamp stand base, and is formed with an insert slot therethrough. The upright clock panel has a lower end formed with an insert portion that is inserted removably into the insert slot. The clock mechanism is mounted on the clock panel.




amp

Deep-ultraviolet chemically-amplified positive photoresist

The invention discloses a deep-ultraviolet chemically-amplified positive photoresist. The deep-ultraviolet chemically-amplified positive photoresist according to one embodiment of the invention includes a cyclopentenyl pimaric acid, a divinyl ether, a photoacid generator and an organic solvent. The deep-ultraviolet chemically-amplified positive photoresist according to the invention has a good sensitivity and a good transparency.




amp

Reference electrodes having an extended lifetime for use in long term amperometric sensors

The present application provides Ag/AgCl based reference electrodes having an extended lifetime that are suitable for use in long term amperometric sensors. Electrochemical sensors equipped with reference electrodes described herein demonstrate considerable stability and extended lifetime in a variety of conditions.




amp

Disposable biopsy devices and methods of obtaining tissue biopsy samples using same

The described invention provides a disposable handheld biopsy device for taking biopsies, the biopsy device comprising a tissue cutting assembly which has features to control the tissue length that will be severed by the cutting assembly; and a vacuum assembly which has features to control the vacuum level. The disposable handheld biopsy device of the described invention is simple, lightweight, portable, and cost effective to manufacture and dispose of.




amp

Chemically amplified resist composition and patterning process

A chemically amplified resist composition comprising a base polymer and an amine quencher in the form of a β-alanine, γ-aminobutyric acid, 5-aminovaleric acid, 6-aminocaproic acid, 7-aminoheptanoic acid. 8-aminooctanoic acid or 9-aminononanoic acid derivative having an unsubstituted carboxyl group has a high contrast of alkaline dissolution in rate before and after exposure and forms a pattern of good profile at a high resolution, minimal roughness and wide DOF.




amp

Methods, systems, and computer readable media for monitored application of mechanical force to samples using acoustic energy and mechanical parameter value extraction using mechanical response models

Methods, systems, and computer readable media for monitored application of mechanical force to samples using acoustic energy and mechanical parameter value extraction using mechanical response models can be used for determining mechanical property parameters of a sample. An exemplary method includes applying acoustic energy to a sample to apply a mechanical force to the sample, measuring a response by the sample during the application of the acoustic energy, measuring a recovery response of the sample following cessation of the application of the acoustic energy, and determining a value for at least one additional mechanical property parameter of the sample based on the response measured during application of the acoustic energy and the recovery response measured following cessation of the application of acoustic energy.




amp

Macro model of operational amplifier and circuit design simulator using the same

The present invention aims to simulate a response more similar to a actual machine while inhibiting load increase in analog operation. Program configuration of the present invention is a component of a simulation program for circuit design, which is executed by a computer. The computer includes an operation portion, a storage portion, a manipulation portion, and a display portion, so that the computer exerts a function of a circuit design simulator, and as a macro model of an operational amplifier for use in the circuit design simulator, enabling the computer to act by simulating a response of the operational amplifier on the circuit design simulator. The macro model of the operational amplifier includes a control portion (LMT1) for generating output exception in the event of input exception or power supply exception of the operational amplifier.




amp

Surface normal computation on noisy sample of points

Various technologies described herein pertain to computing surface normals for points in a point cloud. The point cloud is representative of a measured surface of a physical object. A point in the point cloud can be set as a point of origin, and points in the point cloud can be modeled as electrostatic point charges. Moreover, a point of least electrostatic potential on a sphere centered at the point of origin can be computed as a function of the electrostatic point charges. Further, unit vector with a direction from the point of origin to the point of least electrostatic potential on the sphere can be assigned as a normal for the point of origin.




amp

Systems and methods for controlling damping of magnetic media for heat assisted magnetic recording

Systems and methods for controlling the damping of magnetic media for heat assisted magnetic recording are provided. One such system includes a heat sink layer, a growth layer on the heat sink layer, a magnetic recording layer on the growth layer, where the growth layer is configured to facilitate a growth of a preselected crystalline structure of the magnetic recording layer, and a capping magnetic recording layer on the magnetic recording layer, the capping recording layer including a first material configured to increase a damping constant of the capping recording layer to a first preselected level.