OneNote 노트북을 공유하려고 하는데 MS쪽 오류라면서 공유가 안된다면.......

흔한 상황은 아닙니다만, Windows 10용 OneNote에서 노트북을 공유하려고 하면 갑자기 마이크로소프트쪽에서 문제가 생겼다면서 노트북 공유가 안되는 경우가 있을 수 있습니다. 잘 쓰다가 이쯤 되면 갑자기 정신이 혼미해지죠. 갑자기 왜? -_-

제 경험상, 이 경우 OneDrive 웹페이지(https://onedrive.live.com)로 로그인하면 분명히 MS가 당신이 bot이 아님을 증명하라고 할겁니다. 문자메시지로 받은 PIN번호를 입력하니 바로 풀어주더군요.

어이 마이크로소프트씨, 우리 집사람이 나보고 인공지능 탑재형 로봇같다고 뭐라고 그러긴 하지만, 나 분명히 인간 맞거든? -_-

If your OneNote complains that your notebook can't be shared because MS has some problem.......

This is rare condition, but sometimes OneNote for Windows 10 complains that your notebook can't be shared because there's something from Microsoft side. And you have no idea where and why.

In this case(as I experienced), log in to OneDrive web page(https://onedrive.live.com). And I'm sure that MS will ask you to prove you're not a bot(but why?). I proved myself by confirming a PIN number vis SMS.

Hey Microsoft, though my wife complains that I'm like an A.I.(artificial intelligence)-installed robot, I'm more human than a bot. :P

If deleted OneNote notebook still shows in your OneNote for Windows 10 (UWP) application......

Yes. I'm sure so many people experienced it. You surely deleted your notebook from OneNote for Windows and OneDrive, but if you click More Notebooks you'll see your deleted notebook is still on the list. What's more, if you try to open them, it says OneNote failed to open them. What the hell?
So called Phantom Notebook by someone, this is quite a nuisance. And I'm sure you may also have seen a lot of "solutions" when you have MS Office 2016 - clear Recent in OneNote 2016. Well, the problem arises when you don't have MS Office. And everyone will agree that it's quite too much to subscribe to Office 365 to remove the list......

But did you know that there's one more location where you can access and clear that Recent? You can't find it in OneDrive. It's on Office.com.

Oh yeah. https://www.office.com/ ← Log in here.

If you visit the page and log in, you'll see the list of recently opened documents, and you can also see your deleted OneNote notebooks. You can safely remove those 'phantoms' by clicking ... icon in the middle of the list; after that, go to OneNote Online or OneNote for Windows 10, you can see your list is finally clean now. :)

Hope this helps if you're uncomfortable with it.

OneNote for Windows 10 (UWP)에서 지운 노트북이 계속 보인다면......

예. 아마 많은 분들이 경험하셨을겁니다. 분명히 OneNote for Windows와 OneDrive에서 노트북을 지웠는데 OneNote의 전자 필기장 더 보기를 선택하면 지워진 노트북이 목록에 그대로 떠있는 경우가 있습니다. 해외에서는 Phantom Notebook이라는 표현을 쓰기도 하는 것 같더군요.
뭐, OneNote 2016을 쓰고 있다면 Recent를 지워서 해결할 수 있는데, 문제는 OneNote 2016을 쓰지 않는 경우입니다. 목록 지우자고 Office 365를 구매하는건 좀 오버인 것 같고......

그런데 이 최근 문서 목록을 지울 수 있는 위치가 한군데 더 있습니다. OneDrive에서는 찾을 수 없고요, Office.com으로 로그인하면 바로 나옵니다(-_-).

예. https://www.office.com/ ← 바로 여깁니다.

여기 가시면 여태까지 열었던 문서들의 목록이 나오고, 그중에 지워진 OneNote 노트북도 보이실겁니다. 중간의 ... 아이콘을 클릭하시면 바로 해당 목록을 삭제하실 수 있고, 삭제하신 뒤 OneNote Online이나 OneNote for Windows 10을 열어서 확인해보시면 지워진 노트북이 보이지 않는 것을 확인하실 수 있으실겁니다.

혹시 이것때문에 많이 불편하신 분이 계셨다면 도움이 되셨길 바랍니다.

Choosing a database

Nowadays I'm developing a new product and I'm stuck with choosing the "right" database.
 Well, today we have a wide variety of choices including NoSQL, but too many choices makes me more difficult on selection. I have to consider more things, and I have no idea on how the users will use the product. In my situation I concluded NoSQL is not the way so I'm considering three among SQL engines, but all the candidates bite me on some area.
  1. SQLite: unlike what others think, SQLite has no problems at all on using in production environment. It's stable and FAST. Especially, it's so "lightning" fast that the spiral booster is always turned on(c.f. Cyber Formula). In almost all cases it overwhelms the others. However, it doesn't support concurrent write. To do it, I have to make a wrapper to do it for the database. OTL
  2. PostgreSQL: magnificent. I dare to say it's the best in the world of open source. Though it is based on SQL(I know it's ORDB, but anyway) yet supports NoSQL too. The problem is it's damn sloooooooooooooow like snail and consumes a lot of resources. I can tune it to make it faster but still it lacks some speed.
  3. MariaDB: Fast. I see the speed on most of SQL commands I use. If I use Aria with some setup, in some (limited) conditions it can be faster than SQLite. However, it sometimes hits my back hard. Pretty hard. Even just now, I found a 2-second query suddenly took 11 minutes. And now it takes 42 seconds. Hey you seal?
From the viewpoint of a developer, speed is important, but the more important is whether it's foreseeable or not. If it's slow I can tune it hard, and if it's still slow I can make the application to do another thing concurrently when doing slow stuff, but if the performance is that random, simply I can't use it.

Well, I think I have to ride the elephant again and drop my belief to the Holy Mother.
(or making with the database for missiles......)


데이터베이스 선택의 문제

작금 제품을 개발하면서 가장 커다란 과제중 하나가 데이터베이스 선택입니다.

뭐, 요즘은 NoSQL 포함해서 다양한 상황에 부합하는 여러 제품들이 나와있습니다만, 그렇기 때문에 더 선택이 어려워지기도 합니다. 고려해야 할 사항도 많을 뿐더러, 사용자가 실제로 이 제품을 어떻게 쓸지도 솔직히 예측이 쉽지 않기 때문에 더 그렇습니다. 저같은 경우는 NoSQL은 아직 아닌 것 같아서 SQL들 중에 고르고 있는데...... 이게 난감하네요. 현재 세 가지를 고려하고 있는데, 셋 다 뭔가 하나씩 부족합니다.
  1. SQLite: 많은 사람들의 생각과는 다르게, SQLite를 제품에 적용하는데는 아무런 문제가 없습니다. 안정적이고, 빠릅니다. 속력만 놓고 보면 스파이럴 부스터를 항시 켜놓은 느낌입니다. 모든 경우에서 밑의 두 개를 말 그대로 '발라버립니다.' 그런데 concurrency 지원이 안됩니다. 굳이 하려면 직접 만들어야 해요. OTL
  2. PostgreSQL: 오픈소스계 최강입니다. SQL이면서 NoSQL 기능까지 같이 들어있는...... 단점이라면 (특히 쓰기가) 거북이처럼 느리고, 자원 소모가 상당하다는 겁니다. 튜닝을 좀 하면 빨라지긴 하는데, 그래도 제가 원하는 수준까지 끌어내기에는 부족합니다. OTL
  3. MariaDB: 빠릅니다. 주로 사용하는 구문이 빠르게 움직입니다. Storage engine을 Aria로 놓고 설정을 좀 해놓으면 특정 상황에서는 SQLite보다 더 빨라지기도 합니다(......). 단점이라면 가끔 예측 불가능한 행동을 한다는 거죠. 방금전에도 2초면 끝나던 query 하나가 갑자기 11분 넘게 뻘뻘대더니만 지금은 인풋 한번 수행시간이 평균 42초가 되었습니다(......OTL).
무언가를 만드는 사람의 입장에서는 속도도 중요하지만 더 중요한건 예측 가능성인 것 같습니다. 만일 뭔가 느리다면 속도를 최대한 끌어올리고, 그래도 안되면 느린 작업을 하는 동안에 다른 작업을 수행하게 만들면 되는데, 작업이 저렇게 예측 불가능하게 들쭉날쭉하게 움직이면 답이 안 나오더군요.

뭐, 아무래도 믿었던 성모님으로의 신앙(?)을 버리고 다시 코끼리 등 위에 올라타야 될 것 같습니다.
(아니면 미사일 DB로 뚝딱뚝딱 만들거나......)

DB insertion speed test

To be used in my work, I tested which database inserts the records the fastest. Well, actually it was not much - I just created a table with integer(PK)/timestamp/integer and inserted 1 million records with only PK changing.

Benchmark environment is as follows:
  • Dell Inspiron 7373/i5 8th generation
  • Windows 10 Home
  • Target database(all 32bits)
    • PostgreSQL 10.6: used libpq
    • FIrebird 3.0.3: used OO API (C++)
    • SQLite3: #include <sqlite3.h> // ...... :P
And here comes the results and some remarks. I hope it would help visitors.
(I'm not that much good enough to make something open sourced, so this is the best I can offer to the community...... ;) )
  • Insertion speed
    • 1: SQLite, in-memory database: 2 seconds
    • 2: PostgreSQL, COPY: 5 seconds
    • 3: PostgreSQL, bulk insert: 7 seconds
    • 4: Firebird, bulk insert: 10 seconds
    • 5: SQLite, save to file: 56 seconds
  • Disk I/O
    • Thanks to Windows kernel, if the system receives too many small I/Os, it burdens disk too much, making it to the bottleneck
    • When using SQLite to save the result to disk where bulk insertion is impossible, disk I/O hit 100%
    • In Firebird, bulk insertion is implemented via PSQL, where you send a number of records and the each INSERT line in PSQL sequentially inserts the records; still it burdens the disk I/O very high(around 50%), though lower than SQLite
    • In Firebird, set the page size to at least 8192 to lessen disk I/O burdens
  • Bulk insertion
    • We can speed up the insertion using bulk insertion, but we have some speed bottleneck, regardless of disk I/O.
    • Firebird: 10 records at once, regardless of page size
      • Using stored procedure
    • PostgreSQL: 40 records show the maximum performance
  • PostgreSQL
    • COPY(source: CSV) is incredibly fast. Even the official documentation recommends COPY in bulk insertion
    • In libpq, the speed is around same whether you send the records in either text or binary
  • Miscellany
    • It's far faster to use the official interface directly rather than using any wrapper. When testing Firebird at first, with SOCI it took 59 seconds, while after applying the same logic to Firebird OO API directly the time taken is shrunk to only 20-something seconds.
That's all. Please let me know if you have any questions or comments. =_=/

DB insertion 속도 테스트

업무상 필요로 인해 어느 DB가 record insertion을 제일 빠르게 하는지를 테스트하게 되었습니다. 뭐 대단한걸 한건 아니고, integer(PK)/timestamp/integer로 구성된 테이블에서 PK값만 바꾸고 나머지는 고정값으로 해서 1백만개 레코드를 일괄 등록하는 프로그램을 만들어 돌려봤습니다.

대상 환경은 이렇습니다
  • Dell Inspiron 7373/i5 8세대 모델
  • Windows 10 Home
  • 대상 DB(모두 32비트 모델)
    • PostgreSQL 10.6: libpq 사용
    • FIrebird 3.0.3: OO API (C++) 사용
    • SQLite3: #include <sqlite3.h> // ...... :P
결과 및 시사점을 정리합니다. 도움이 되셨으면 합니다.
(아직 뭔가를 만들어 open source로 만들어 내놓을 정도의 실력이 되지는 않으니 이런거라도......)
  • Insertion 속도
    • 1위: SQLite, in-memory database: 2초
    • 2위: PostgreSQL, COPY: 5초
    • 3위: PostgreSQL, bulk insert: 7초
    • 4위: Firebird, bulk insert: 10초
    • 5위: SQLite, 파일에 저장: 56초
  • Disk I/O 관련
    • Windows 커널 특성상 small I/O가 많아지면 disk에 부담이 너무 많이 가 bottleneck이 됨
    • Bulk insert가 불가능한 SQLite 파일 저장 조건에서 disk I/O가 100%가 됨
    • Firebird의 경우, PSQL을 사용하여 bulk insert를 구현하는 형태로, 다수의 레코드를 한번에 받아 디스크에 개별 INSERT 명령어를 사용하여 순차적으로 쓰는 형태로 구현되므로, SQLite급까지는 아니더라도 disk I/O가 높게 일어남(disk I/O 50%)
    • Firebird의 경우 page size를 최소 8192이상으로 가져가는 것이 disk I/O 부하 감소에 도움이 됨
  • Bulk insertion 관련
    • Bulk insertion을 이용하여 insertion 속도를 올릴 수 있으나, 일정 수준 이상을 넘어서면 속도가 더이상 올라가지 않음. 이는 disk I/O와는 별개임
    • Firebird: 10개 수준에서 최고속력을 보임(page size와 상관없음)
      • Sotred procedure 
    • PostgreSQL: 40개 수준에서 최고속력을 보임
  • PostgreSQL 관련
    • COPY(원본: CSV 기반)가 규격외로 빠른 속력을 보임. 실제로 공식 메뉴얼에서도 bulk insertion에서는 COPY를 추천함
    • libpq에서 insertion 데이터를 보낼때 데이터를 text와 binary 중 어느 형태로 보내도 소요 시간은 동일함
  • 기타
    • 각 DB에서 제공하는 직접 연결 인터페이스를 사용하는 것이 wrapper를 사용하는 것보다 훨씬 빠름. Firebird로 최초 테스트시, SOCI 적용시 59초가 소요되었으나 Firebird OO API로 동일 로직 구현시 20초대에서 완료됨
이정도입니다. 혹시 궁금하신 점이 있으시면 문의 주세요. =_=/

Compile qdoc in Qt 5.11 with MinGW

From Qqt 5.11, qdoc depends on libclang.
https://bugreports.qt.io/browse/QTBUG-66353
Qt Creator is also said to use clang codemodel as their main C++ parser instead of their homemade one, and now qdoc follows.

OK. Good. Understandable..... But, we have a problem - libclang is not build with MinGW 5.3. LLVM buildbot claims that they use GCC 5.3, internally they seem to use MinGW 7.1. It looks like Qt will upgrade their MinGW to 7.3 from Qt 5.12(7.1 looks buggy so they have to use 7.3 instead).
https://bugreports.qt.io/browse/QTBUG-66015?focusedCommentId=402146&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-402146
So, now we have the core reason and solution. But in Qt 5.11, due to lack of time thanks to that target release date, in 5.11 Qt still uses MinGW 5.3 but they blocked building qdoc. And Qt 5.12, which is expected to solve the issue, will be released some time around Nov.29th. Yep. MinGW users should endure the pain of not-accessible-at-all to the documentation, which is one of the selling point for Qt(you can use online docs, but it's still unconvenient).

But, who are we? We're developers. And Qt is open source project. We can itch wherever is itching. So, I built qdoc with MinGW.

Prerequisites are as follows:
  1. Source code of Qt
  2. MinGW-w64: 7.3 or higher
  3. LLVM library prebuilt by Qt: it's a bit hard to find....... But here you go:
    http://download.qt.io/development_releases/prebuilt/libclang/
If you're going to build Qt Creator too, choose libclang-release_50-windows-mingw series(as of current clang codemodel supports only libclang 5.0).

To build qdoc by yourself, unzip Qt source code and libclang, and change the project file of qdoc. The location is as follows:
QtSourceCode/qttools/src/qdoc/qdoc.pro

Put the following two lines into the top of the project file:
  • INCLUDEPATH+=/Qt_prebuilt_clang/unzipped/include
  • LIBS+=-L/Qt_prebuilt_clang/unzipped/lib -llibclang.dll
After that, build Qt as usual using configure and mingw32-make, and manually build qdoc.pro.

It would be great if there's someone who experienced inconveniences due to lack of documentation with MinGW, but is relieved with this.

Qt 5.11에서 MinGW로 qdoc 컴파일하기

Qt 5.11부터 qdoc이 libclang에 의존성을 가지게 되었습니다.
https://bugreports.qt.io/browse/QTBUG-66353

Qt Creator도 4.7부터 자체 C++ parser 대신 clang codemodel을 메인으로 가져가겠다고 했는데, qdoc도 clang에 의존하게 되었네요.

뭐, 다 좋은데...... 문제는 이 libclang이 MinGW 5.3에서는 빌드가 안된다는 겁니다. LLVM buildbot은 GCC 5.3으로 빌드한다고 주장하는 것 같습니다만, 실제로 내부에서 돌아가는 컴파일러는 MinGW 7.1이라고 합니다. 해서, 이런저런 사유로 인해 Qt 5.12에서는 MinGW 버전을 7.3으로 올리겠다고 내부 입장을 정리한 것 같습니다(7.1은 눈에 띄는 버그들이 있어서, 7.3을 써야 한다고 하네요).
https://bugreports.qt.io/browse/QTBUG-66015?focusedCommentId=402146&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-402146

문제의 원인과 해결책은 이미 나온 듯 합니다만, Qt 5.11의 경우 release date가 너무 촉박한 터라, Qt에서는 MinGW의 경우 5.3을 그대로 사용하고, 그 대신에 qdoc의 빌드를 막아버렸습니다. 그리고 이 문제를 해결할 것으로 예상되는 Qt 5.12의 목표 release date는 무려 11월 29일입니다. 옙. MinGW 사용자들은 MinGW를 이용한다는 이유 하나만으로 올해 11월 말까지 Qt의 자랑인 documentation을 쓰기가 어려운 상황이 되어버렸습니다(온라인이라는 방법도 있습니다만, 웹브라우저를 통한 검색은 역시 많이 번거롭죠).

하지만 우리가 누굽니까. 우리는 개발자입니다. 그리고 Qt는 오픈소스로 제공됩니다. 예. 필요하면 소스코드를 뜯어고치면(-_-) 됩니다. 그래서 MinGW로 qdoc을 빌드해봤습니다.

준비물은 다음과 같습니다:
  1. Qt 소스코드
  2. MinGW-w64 7.3 이상(-_-)
  3. Qt에서 제공하는 비공식 LLVM prebuilt library: 이게 좀 찾기가 까다로운데...... 여기서 구하실 수 있습니다:
    http://download.qt.io/development_releases/prebuilt/libclang/
Qt Creator도 함께 빌드하실 생각이시라면 libclang-release_50-windows-mingw 시리즈를 선택하세요(clang codemodel은 현재 libclang 5.0만을 지원합니다)

qdoc을 직접 빌드하시려면, 적절한 곳에 Qt 소스코드와 libclang의 압축을 풀고, qdoc의 프로젝트 파일을 변경합니다. 위치는 아래와 같습니다:
QtSourceCode/qttools/src/qdoc/qdoc.pro

그리고 맨 윗줄에 아래의 두 줄을 추가합니다:
  • INCLUDEPATH+=/Qt_prebuilt_clang/unzipped/include
  • LIBS+=-L/Qt_prebuilt_clang/unzipped/lib -llibclang.dll
이후 configure -> mingw32-make를 실행하여 Qt를 빌드한 후, qdoc.pro를 별도로 빌드해주시면 됩니다.

혹시 MinGW로 Qt를 직접 빌드하시면서 Qt documentation이 없어서 불편을 겪으셨던 분들이 계시다면, 이걸로 고생이 덜해지시길 바랍니다.

MinGW 8.1.0 vs. VC++2017: performance benchmark

I don't know why, but after writing down that I'm going to VC++2017 yesterday I took a simple benchmark testing. No, it was not that much delicate: it reads a file via ifstream and in the memory it parses the data, and the performance was checked with GetTickCount(). The result was that MinGW was always 10~30% faster than VC++2017.

Hmmm...... Do I have to get back to MinGW?

MinGW 8.1.0 vs. VC++2017: 수행성능 비교

어제 VC++2017로 가겠다고 써놓고 무슨 바람이 불었는지 간단한 퍼포먼스 벤치마킹을 수행했습니다. 제가 능력이 출중해서 정교한 실험을 한 건 아니고, 그냥 ifstream으로 파일을 읽은 후 메모리에 올려서 약간의 parsing을 하는 작업을 GetTickCount()로 찍어서 체크해봤는데, 제 사용 사례의 경우에는 MinGW가 VC++2017보다 항상 10~30%정도 더 빠르더군요.

MinGW로 돌아가야 되나...... 싶습니다. -_-

Going Native

A lot of things happened behind the scenes. Due to some unflexible cash flow my company closed Korea branch, and I moved to a small company and got dual role of system engineer and developer. Well, the company first expected to do engineering and development works in 50:50 manner, but in practice I concentrate on development itself. I think it's a good start for a ex-hobbiest-programmer where the customer changed their feedback from negative to positive after my application is delivered to them.

And, during the time I thought of the techonlogy stacks I should bring with myself. Though Qt can cover everything from desktop to mobile, and is equipped with a lot of powerful features, after applying the tool to the work situation things dragged me of my legs. For example:

  1. It's BIG. HUGE. OK. It's good to have a lot of things, but the size of library grows bigger with any new addition of the features. For simple tasks, I can't avoid the feeling of using zweihander to grass cutting.
  2. SLOW. From Qt Model-View framework which is a failure and needs restructuring, to container classes like QList or QLinkedList saying "we're concentraing on convenience while STL stresses on raw speed," and the speed of database manipulation is not that good eighter. For databases, I found out it's far faster to use SOCI after converting things from QString to std::string. From my experience, for the same task Qt took about twice or more time to perform the same task against others(e.g. STL or wxWidgets).
  3. Developer is "locked" into the Qt ecosystem. Well, I admit its rich feature gives developers more development convenience, but after adopting to Qt I don't feel good with using it with other libraries or environments. Sometimes I feel I'm working on Java instead of C++, in terms of not only structue but also running performance of the system(meaning that it's slow, unlike C++). During coding, I'm not sure whether I'm using Java or c++. Ah, of course signal-slot mechanism and QString is such a technologicla advance in a decade.
  4. It has some holes here and there, for example, Qt Quick. I love the approach and structure of Qt Quick and I admit it's such an accomplishment, I see occasional "broken" frames on Windows/Intel environment, or I see too long time for the first run on Andorid(they existed until Qt 5.9. I heard that the bytecode compilation in Qt 5.11 resolved the slow first start a lot, but I had no chance to test it). Or, for me a MinGW user, in Qt 5.10 qdoc(and that Qt documentation) suddenly became unavailable because MinGW 5.3 couldn't compile libclang(......). And the new autompletion with libclang in Qt Creator is said to be toooooo slow....... And so on and on and on. 
  5. Sometimes there are things infeasible to programmers. Qt hides the implementation details in its private layer, which makes it too difficult to debug when some bad things happen, especially when it's related with some specific feature of Qt itself. What's more, due to the behavior of QURL to force percent-encoding(and which is malfunction in specific context), I had to give up QNetworkAccess and adopt libcurl(with additional coding where I had to implement about 3/4 of my network coding again......).


Well, anyway it's BIG enough to be tackled from anywhere, but you know, now I can say there's no one library/framework that fits too all. So I looked for any alternatives and asked for help from my close friends. And guess what? Now I'm dropping the dependency against Qt and bringing development staks close to native "recommended" environment.

  1. C++ / wxWidgets & more: whoever says what, C++ is my main development platform. And I concluded wxWdigets, thin wrapper of native widgets, can replace Qt Widgets. Thinking of my past experience, I had to save my time so that I had to use Qt Widgets anyway(and Qt Quick took relatively too much time to develop). wxWidgets consumes less memory and bootstrapping is faster, which fits to my philosophy of "relatively fast running."
  2. Ah. I changed my compiler from MinGW to VC++. I was using MinGW to expect consistency against platforms, namely Windows and Linux, but nowadays I had to use some Windows API which doesn't exist in MinGW(:P). And it looks like VC++ looks good from VC++ 2017. I think I should conquer the differences between compilers with some nuts.
  3. Javascript: Javascript is the language of web! As soon as I'm done with my current project, I'd like to start learning vue.js and node.js(especially Express.js) and apply them to the work.
  4. Kotlin: OK. Now the desktop is done, but still "mobile" remains. Kotlin is native in Android(and I strongly feel that Google pushes it harder than ever after it lost the case against Oracle), and when Kotlin/Native is copmlete iOS can be "natively" supported. It's a good choice for me, who won't touch Apple ecosystem for a few years but no idea after that.


Originally I added Python and Rust to the list, but I found out that I don't have to dig deep Python though it's used in the product I currently engineer, and I concluded that from Rust I can adopt the structure to C++ so I don't have to worry much. And I also considered Go but its structure was not of my taste......

So that's all. At present, I just want to close the current project and have some time to learn Javascript.

네이티브로 가자!

조용했던 그동안 많은 일이 있었습니다. 다니던 회사가 자금사정이 악화되어 한국지사가 폐쇄되었고, 여차저차해서 작은 회사의 모 제품 시스템 엔지니어 겸 개발자가 되었습니다. 그리고 원래대로라면 엔지니어링과 개발이 50:50이 되어야 하는데, 또 어쩌다보니 엔지니어링보다는 개발에 집중하고 있습니다. 뭐, 제 개발품으로 인해 그간 계속 부정적이기만 했던 고객사의 피드백이 최초로 긍정적으로 바뀌었다고 하니, 20년동안 취미로만 프로그래밍을 하던 사람의 실적치고는 꽤 괜찮은 출발인 것 같습니다.

그리고 그동안 제가 가져가야 할 개발환경에 대해 많이 생각했습니다. 비록 Qt가 데스크탑에서 모바일에 이르기까지 다양한 플랫폼을 지원하고 매우 강력한 기능들이 많다지만, 실제로 업무현장에 적용해보니 확실히 몇가지 문제들이 제 발목을 잡더군요. 몇가지를 예로 들자면......

  1. 덩치가 큽니다. 기능이 많은건 좋은데, 그 반대급부로 라이브러리의 크기가 계속 커져가고 있습니다. 닭 잡는데 소 잡는 칼을 쓰는 듯한 느낌을 지울 수 없습니다.
  2. 느립니다. 많은 사람들로부터 전면 개보수가 필요하다고 평가받는 Qt Model-View framework부터 시작해서, QList, QLinkedList 등 container class들은 아예 "STL이 속도라면 우린 편의성"이 모토고, 데이터베이스 처리도 썩 그렇게 좋은 성능을 보여주지 못하고 있습니다. DB는 Qt datbase framework보다는 QString을 std::string으로 변환한 뒤에 SOCI를 쓰는게 훨씬 빠르더군요.
  3. 개발자가 Qt의 개발환경에 '갇힙니다.' Qt가 다방면으로 매우 많은 기능을 지원하고, 그로 인해 개발 편의성이 올라가는 것은 누구나 인정하는 바입니다만, 한번 Qt의 개발환경을 사용하고 나게 되면 다른 라이브러리나 환경을 접목시키기가 쉽지 않다는 느낌을 받습니다. 가끔씩은 매우 Java같은 느낌의 C++ 프레임워크라는 느낌이 들더군요. 구조만 그러면 모르겠는데, 프로그램의 수행속도도 C++보다는 Java에 더 가깝다는 느낌을 많이 받습니다(즉, C++답지 않게 느리게 느껴집니다). 개발을 하고 있다보면 내가 C++을 쓰는지 Java를 쓰는지 살짝 헷갈리기도 합니다(......). 아, 물론 signal-slot 매커니즘과 QString은 인정합니다.
  4. 꼭 뭔가 하나씩 빵꾸가 납니다. 가장 대표적인게 Qt Quick입니다. 비록 Qt Quick은 기능과 접근방법 모두 훌륭하고, 대단한 기술적 성공이긴 합니다만, Windows/Intel 비디오카드 환경에서 화면 크기 변경시에 프레임이 깨져서 눈에 거슬린다던가, Android로 빌드할 경우 최초 실행시 boottime이 너무 길어진다던가 하는 등의 문제점이 있습니다(최소한 5.9까지 상존했던 문제입니다. 5.11에서는 bytecode compilation 덕에 많이 좋아졌다고는 들었습니다만, 테스트는 못해봤네요). 아니면 저의 경우 플랫폼간 컴파일러의 일관적 행태를 위해 MinGW를 쓰는데, Qt 5.11의 경우 현재 지원하는 MinGW 5.3에서 libclang이 빌드되지 않는다는 이유 하나만으로 qdoc을 빌드하지 않게 막았다던가(......) 하는 등의 자잘한 건들이 생깁니다. 아울러 Qt Creator의 autocompletion을 libclang 기반으로 바꾼다고 선언했는데, 너무 느리다고 말이 많기도 하고...... 
  5. 가끔 뜬구름 잡는 듯한 느낌이 있습니다. Qt가 개발을 편하게 하게 하기 위하 많은 기능을 지원하긴 하는데, 이게 프로그램 동작의 많은 부분을 숨겨놓은 터라 가끔 문제가 생기면 어디서 뭘 봐야 할지 감이 안 잡히는 상황들이 발생합니다. 특히 그게 Qt의 특정 기능과 직접적으로 연관된 경우는 더 그렇습니다. 심지어 최근에는 QURL에서 퍼센트 인코딩을 강제하는(문제는 이게 특정 상황에서는 적용되기가 어렵다는) 특징때문에 그 편한 QNetworkAcccessManager을 쓰지 못하고 libcurl을 써야 했던(그리고 네트웍 코드의 3/4을 갈아엎어야 했던......-_-) 상황도 있었습니다.

뭐, 프레임워크의 덩치가 워낙 크다보니 말이 많긴 하겠습니다만, 하여간 실무에 적용하다보니 이런저런 문제점들이 보이더군요. 그래서 여러가지 대안도 찾아보고, 주변 분들의 조언도 구한 끝에 Qt에 대한 의존성을 버리고, 네이티브에 가까운 개발환경을 가져가는게 좋겠다는 결론을 내렸습니다.

  1. C++ / wxWidgets & more: C++은 제 메인 개발환경이니 필히 가져가야 하고, GUI는 네이티브 위젯의 thin wrapper인 wxWidgets를 쓰면 되겠다는 결론을 내렸습니다. 시간이 없어 급하게 개발하다보면 Qt Quick은 항상 그림의 떡이고, 맨날 Qt Widgets만 쓰던 입장에서는 차라리 네이티브라 RAM도 덜 먹고 bootstraping도 빠른 wxWidgets가 답이겠더군요.
  2. 하는 김에 컴파일러도 MinGW에서 VC++로 변경했습니다. 그동안에는 Windows와 Linux 사이에서 컴파일러가 일관적으로 돌아가는걸 감안하느라 MinGW를 썼는데, 가끔 Windows API를 쓸 일이 생기면 꼭 MinGW에는 없는 헤더만 찾게 되더군요(-_-). VC++2017 자체도 많이 좋아진 듯 하고...... 컴파일러간 차이는 그냥 근성으로 극복해봐야 할 듯 합니다.
  3. Javascript: Web은 역시 Javascript가 native입죠(......). 일단 현재 프로젝트가 어느정도 정리되면 vue.js와 node.js(Express.js)를 중심으로 천천히 실무에 적용해볼 계획입니다.
  4. Kotlin: 맨날 desktop에서 놀다보니 모바일은 어떻게 가져가야 하는가 하는 문제가 남는데, Kotlin은 일단 Android에서는 native고(특히나 Google이 Oracle과의 소송에서 패한 뒤로는 더 화끈하게 밀어주고 있다는 느낌을 많이 받았습니다), Kotlin/Native가 완성되면 iOS도 네이티브로 개발이 가능해지는 만큼 꽤 괜찮겠다는 결론을 내렸습니다. 특히나 저처럼 앞으로 근 몇년간은 Apple쪽 생태계를 건드릴 일이 없지만 언제가 건드릴지도 모르는 경우에는 더 그렇고요.

원래는 여기에 Python과 Rust가 추가되어 있었습니다만, Python은 현재 엔지니어링을 진행중인 제품에서 쓰고 있긴 하지만 그렇게 깊게 들어갈 필요가 없고, Rust는 C++에서 약간만 조심하면 되는터라 당장 큰 문제는 되지 않겠다는 결론이 나서 일단은 버리기로 했습니다. 그 외에 Go도 후보선상에 살짝 올라와 있었지만 언어 구조가 영 제 취향이 아니라 포기했고......

오랜만에 잡생각을 정리할 겸 해서 올려봤습니다. 지금은 하던 일 잘 마무리하고 Javascript 공부에 할애할 시간을 확보했으면 좋겠네요.

If your control can't fetch keyboard focus in Qt Quick......

Use forceActiveFocus() method.

To get the keyboard focus, you have to set focus:true from the very root of all visual parents the control is attached. If the structure becomes complicated, you have no idea on where to "power on" and where not. In that case, use forceActiveFocus() to make any necessary attribute changes at once.

Man I had to throw away yesterday not knowing this. OTL

Qt Quick에서 뭔 짓을 해도 컨트롤이 키보드 포커스를 가져오지 못한다면......

forceActiveFocus() method를 사용하면 됩니다.

원래 키보드 포커스는 visual parent에서 해당 컨트롤의 모든 부모계통 컨트롤이 속성을 focus: true로 놓도록 설정되어야 잡히는데, 구조가 복잡해지면 어느게 어느거고 어떻게 영향을 받는지 감이 안 잡히는 상황이 발생합니다. 이때 forceActiveFocus()를 사용하면 필요한 부분을 다 알아서 자동으로 바꿔줍니다.

......이거 몰라서 어제 하루 날려먹었네요. OTL

블로그를 이전합니다

뭐, 이런 작은 변방의 블로그에 관심있으신 분들은 아무도 없으시리라 생각합니다만...... (웃음) 블로그 플랫폼을 블로거에서 dev.to로 옮겼습니다. 새 URL은 아래와 같습니다: https://dev.to/teminian 새로운 거처에서 뵙겠습니...

Popular in Code{nested}